如果T
是赋值运算符默认签名的类类型,那么我们可以这样写:
T const &ref = ( T{} = something );
创建一个悬空引用。但是,带有签名:
T &operator=(T t) &
上面带有悬空引用的代码将无法编译。这将防止某些我们返回指定临时对象的左值的情况——不希望出现的情况,因为它们会导致悬空引用。
有什么理由不这样做吗?我们会禁用赋值运算符的任何有效用例吗?
我认为同样的评论也适用于复合赋值运算符,+=
等。更现实的情况可能是:
std::string const &s = std::string("Hello, ") += "world!";
在运行时 UB 之前,拼写错误不会被注意到。
最佳答案
根据我的经验,在极少数情况下您确实想要分配给右值,写作
template<class T>
std::remove_reference_t<T>& as_lvalue(T&&t){return t;}
并用 as_lvalue( tmp() ) = foo
代替 tmp()=foo
并不是一个巨大的障碍。这确实意味着 确实 分配给右值的偶尔的代码现在要中断了;我个人怀疑大多数此类情况实际上是未发现的错误。
在法兰克福的 C++11 标准化期间(2009/07)考虑将 std
中的每个类型限制为 operator=
上的左值限制。 minutes中记录的解析推理是:
N2819, "N2819 Ref-Qualifiers for assignment operators of the Standard Library" was initially considered by the LWG. This proposal sought to change 350 copy-assignment operators in the C++ standard library to prevent assignment operations in which the left operand is an rvalue. Due to the large number of changes required, the proposal was sent to EWG, with the request that the default behavior for implicit copy-assignment operators be reconsidered, so that assignment to an rvalue is not permitted. The EWG resolved to maintain the status quo, because of concerns about backwards compatibility.
我读到的意思是“350 次更改?更改语言怎么样?”。 EWG 说“不,语言更改可能会破坏兼容性”。并且该提案可能半途而废。
2009 年,C++11(当时的 C++0x)已经落后于计划。由于该提议涉及对库进行 300 次更改(理论上)可能会导致回归。 session 记录中没有提到其他原因。它因为不值得回归的痛苦而被拒绝(甚至检查回归的频率!)是可以理解的。所以我不会仅仅因为 C++ 在 std
中拒绝了它就假定对这个想法有偏见。
关于c++ - 将赋值运算符标记为左值是否会提高安全性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28598468/