如何避免重载赋值运算符将右值转换为左值?

upd*_*liu 12 c++ c++11

据我所知,返回*this是写超载的常态operator=.但这可能会提升左值的价值!

struct Foo {
  Foo& operator=(const Foo &t) { return *this; }
};

int main() {
  const Foo &ref = Foo();
  //Foo &ref1 = Foo();  // This line won't compile.
  //But the following line compiles. Isn't it dangerous?
  //Also please note that if = is not overloaded, the synthesized operator= will NOT let it compile.
  Foo &ref2 = (Foo() = Foo());

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*e S 7

你是对的.简短的回答是这是合法的,但由于你指出的原因是危险的.

另一个(类似的)示例被添加到C++ 11中,作为标准的一部分,使用rvalue流输出,返回左值引用.

template <class charT, class traits, class T>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>&& os, const T& x);
Run Code Online (Sandbox Code Playgroud)

std::ostream& s = std::ofstream("foo.txt") << "Oh boy";是合法的,但创造了一个悬垂的参考.

我相信C++ 11编译器会允许成员函数限制在对象是左值的情况下,这应该可以让你完全避免这个问题.下面只允许在*this左值时进行赋值,因此它会阻止您意外转换.

struct Foo {
  Foo& operator=(const Foo &t) & { return *this; }
};
Run Code Online (Sandbox Code Playgroud)