看看下面的代码:
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
左值引用。这是非法的,因此编译错误。右值只能绑定到右值引用或左值引用。s
foo()
const
+bar()
另一方面,表达式返回一个左值引用(即 的返回类型operator + ()
),它可以绑定到 的左值引用参数foo()
。
但请注意:您将在此处返回对临时对象的左值引用。虽然在内部使用它foo()
仍然是安全的(当创建它的完整表达式被完全评估时,临时将被销毁,因此在返回之后),如果您将该引用存储在某处并稍后取消引用foo()
,您将获得未定义的行为。
因此,与其将其视为“编译错误的解决方案”,不如将其视为一种蒙住编译器的方法,这样您就可以自由地潜入大麻烦。