它是否提高了将赋值运算符标记为仅限左值的安全性?

M.M*_*M.M 11 c++ operator-overloading assignment-operator c++11

如果T是具有赋值运算符的默认签名的类类型,那么我们可以编写:

T const &ref = ( T{} = something ); 
Run Code Online (Sandbox Code Playgroud)

这创造了一个悬垂的参考.但是,签名:

T &operator=(T t) &
Run Code Online (Sandbox Code Playgroud)

带有悬空引用的上述代码将无法编译.这可以防止我们返回指定临时对象的左值的一些情况 - 不良情况,因为它们可能导致悬空引用.

有没有理由不这样做; 我们是否会禁用赋值运算符的任何有效用例?

我认为相同的注释也可以应用于复合赋值运算符+=等.更现实的情况可能是:

std::string const &s = std::string("Hello, ") += "world!";
Run Code Online (Sandbox Code Playgroud)

在运行时UB之前,拼写错误会被忽视.

Yak*_*ont 7

根据我在极少数情况下的经验,你确实想要分配一个右值,写作

template<class T>
std::remove_reference_t<T>& as_lvalue(T&&t){return t;}
Run Code Online (Sandbox Code Playgroud)

as_lvalue( tmp() ) = foo而不是tmp()=foo不是一个巨大的障碍.它的意思是说的代码偶尔位分配给右值,现在要打破; 我个人会怀疑大多数此类案件实际上是未被捕获的错误.


在法兰克福(2009/07)的C++ 11标准化过程中,考虑限制每种类型的std左值限制operator=.记录在该决议推理分钟是:

N2819,"标准库任务操作员的N2819参考限定符"最初由LWG审议.该提议试图在C++标准库中更改350个复制赋值运算符,以防止左操作数为右值的赋值操作.由于需要进行大量更改,该提案已发送给EWG,并请求重新考虑隐式副本赋值运算符的默认行为,以便不允许赋予rvalue.由于担心向后兼容性,EWG决定维持现状.

我读到这句话说"350个变化?语言变化怎么样?".EWG说:"不,语言的改变可能会破坏兼容性".可能这个提议在葡萄藤上死了.

在2009年,C++ 11(当时的C++ 0x)已经落后于计划.由于该命题涉及对图书馆的300次改变(理论上)可能导致回归.在会议记录中没有提到其他原因.因为不值得回归的痛苦(甚至检查回归频率!)而被拒绝是可以理解的.所以我不会因为C++拒绝它而对这个想法产生偏见std.