看看下面的代码:
struct s
{
s& operator+() {return*this;}
};
void foo(s &) {}
s bar() {}
int main()
{
foo(bar()); //comp error
foo(+bar()); //ok
}
我认为 main() 中的两行应该是等价的,因为编译器优化掉了 operator+(),对吧?接受一个而不接受另一个有什么意义?
看看下面的代码:
struct s
{
s& operator+() {return*this;}
};
void foo(s &) {}
s bar() {}
int main()
{
foo(bar()); //comp error
foo(+bar()); //ok
}
我认为 main() 中的两行应该是等价的,因为编译器优化掉了 operator+(),对吧?接受一个而不接受另一个有什么意义?
该行foo(bar())试图将类型的右值s(由 临时返回)绑定到对(的参数)bar()的非const左值引用。这是非法的,因此编译错误。右值只能绑定到右值引用或左值引用。sfoo()const
+bar()另一方面,表达式返回一个左值引用(即 的返回类型operator + ()),它可以绑定到 的左值引用参数foo()。
但请注意:您将在此处返回对临时对象的左值引用。虽然在内部使用它foo()仍然是安全的(当创建它的完整表达式被完全评估时,临时将被销毁,因此在返回之后),如果您将该引用存储在某处并稍后取消引用foo(),您将获得未定义的行为。
因此,与其将其视为“编译错误的解决方案”,不如将其视为一种蒙住编译器的方法,这样您就可以自由地潜入大麻烦。