返回类型取决于算术运算的顺序.对吗?



考虑以下代码片段:

template <typename U>
struct Un {
    Un (int p) : n {p} {}
    U operator+ (U v) const {
        return U {n + v.n};
    }
    int n {};
};
struct R : Un<R> {
    using Un::Un;
};
struct D : Un<D> {
    using Un::Un;
    D (R v) : Un {v.n} {}
    operator R () const {
        return n;
    }
};

的用法如下:

template <typename T>
void what_type (T t) {
    std::cout << "type R = " << std::is_same<T, R>::value << std::endl;
    std::cout << "type D = " << std::is_same<T, D>::value << std::endl;
}
R r {10};
D d {10};
what_type (r+d);
what_type (d+r);

输出是:

type R = 1
type D = 0
type R = 0
type D = 1

表示在算术表达式中,如果R类型出现在第一个,则整个表达式为R类型,如果D类型出现在第一个,则表达式为D类型。

所以,我的理解是这样的:

r+d中,我们首先创建R类型的对象,然后创建D类型的对象,由于D实现了operator R(),因此将D对象转换为R,实际上得到r+r

d+r中,我们首先创建了D类型的对象,然后是R类型的对象,因为D有一个构造函数,它接受R对象,它从之前创建的r中创建了D对象,这实际上给了我们d+d

我的理解正确吗?或者对于这种情况还有其他规则吗?

你的理解有缺陷。您将二进制operator+定义为成员函数。这意味着作业的左边是固定不变的。对于DR,分别是DR

d+r本质上与d.operator+(r)相同,对于Un<D>返回D。对于r+d来说也是一样的。

在这两个表达式中都"创建"左操作数。

返回类型取决于算术运算的顺序。它是正确吗?

只有在涉及重载操作符时才能为真。对于内置操作符,参数的顺序不影响表达式的类型。

对于重载操作符,表达式的类型取决于重载解析的结果。

考虑一个更简单的例子,操作符被全局重载:
struct A { operator int() const; };
struct B { operator int() const; };
A operator+(A, int);
B operator+(B, int);
A a;
B b;
a + b // resolved as a + (int)b; the type of the expression is A
b + a // resolved as b + (int)a; the type of the expression is B

请注意,如果没有定义B operator+(B, int);, b + a仍然会被解析,但现在是(int)a + (int)b,因此它的类型将是int

最新更新