在我的电脑上运行以下程序
#include <iostream>
class Int {
public:
Int(int x) : val{x} {}
Int operator++() {
std::cout << "Int::operator++()\n";
return ++val;
}
friend Int operator+(Int a, Int b) {
std::cout << "operator+(Int, Int)\n";
return a.val + b.val;
}
friend Int operator*(Int a, Int b) {
std::cout << "operator*(Int, Int)\n";
return a.val * b.val;
}
private:
int val;
};
int main()
{
Int a = 1, b = 2;
b = ++a + b * b;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到了这个输出:
operator*(Int, Int)
Int::operator++()
operator+(Int, Int)
Run Code Online (Sandbox Code Playgroud)
据我所知,前缀的++优先级高于二进制*.但是在上面显示的输出中,前缀++是在二进制之后调用的*!是因为编译器将operator +视为函数调用(导致未指定的行为)?我总是可以考虑重载运算符的功能(这使得行为x = x++定义良好时x是Int)?
谢谢!
是因为编译器将其
operator+视为函数调用(导致未指定的行为)?
是.但请注意,如果++a在之后进行评估并不重要b * b,因为最后,正确地添加了这两个,这符合运算符优先级规则.
没有赋值的表达式相当于:
operator+(a.operator++(), operator*(b, b))
Run Code Online (Sandbox Code Playgroud)
函数参数的评估顺序是未指定的,因此从技术上讲,++a可以在之前进行评估b * b,但也可以相反.
我总是可以考虑重载运算符的功能(这使得行为
x = x++定义良好时x是Int)?
是的,不是.如果Int与"普通"运算符相同,那么就没有(直到C++ 17),因为这将是未定义的行为.但如果Int不改变x,x++例如,那么是.