本文介绍了将赋值运算符标记为仅左值是否可以提高安全性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果T是一个带有默认赋值运算符签名的类类型,那么我们可以这样写:

If T is a class type with the default signature for assignment operator, then we can write:

T const &ref = ( T{} = something );

创建一个悬空引用.但是,带有签名:

which creates a dangling reference. However, with the signature:

T &operator=(T t) &

上面带有悬空引用的代码将无法编译.这将防止我们返回指定临时对象的左值的某些情况——不希望出现的情况,因为它们可能导致悬空引用.

the above code with dangling reference will fail to compile. This would prevent some situations where we return an lvalue that designates a temporary object -- undesirable situations because they can lead to dangling references.

有什么理由不这样做吗?我们会禁用赋值运算符的任何有效用例吗?

Is there any reason not to do this; would we be disabling any valid use cases for the assignment operators?

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

I think the same comments can apply to the compound assignment operators too, += etc. A more realistic case might be:

std::string const &s = std::string("Hello, ") += "world!";

直到运行时 UB 才会注意到错字.

where the typo would go unnoticed until runtime UB.

推荐答案

根据我在极少数情况下的经验,您确实希望分配给右值,写作

In my experience in the rare case you do want to assign to an rvalue, writing

template<class T>
std::remove_reference_t<T>& as_lvalue(T&&t){return t;}

并且使用 as_lvalue( tmp() ) = foo 而不是 tmp()=foo 并不是一个巨大的障碍.这确实意味着确实分配给右值的偶尔代码现在会中断;我个人怀疑大多数此类情况实际上是未捕获的错误.

and doing as_lvalue( tmp() ) = foo instead of tmp()=foo is not a huge barrier. It does mean that the occasional bit of code that did assign to an rvalue is now going to break; I personally would suspect most such cases are actually uncaught bugs.

在法兰克福 (2009/07) 的 C++11 标准化期间考虑将 std 中的每个类型限制为对 operator= 进行左值限制.分钟中记录的解析推理是:

Restricting every type in std to be lvalue-restricted on operator= was considered during C++11 standardization in Frankfurt (2009/07). The resolution reasoning recorded in the minutes was:

N2819, "N2819 Ref-Qualifiers for标准库的赋值运算符"最初是由 LWG 考虑的.该提案试图更改 C++ 标准库中的 350 个复制赋值运算符,以防止左操作数为右值的赋值操作.由于需要进行大量更改,该提案已发送给 EWG,并要求重新考虑隐式复制赋值运算符的默认行为,从而不允许对右值进行赋值.由于担心向后兼容性,EWG 决定维持现状.

我读的是350个变化?语言变化怎么样?".EWG 说不,语言更改可能会破坏兼容性".并且这个提议可能夭折了.

I read that as saying "350 changes? How about a language change?". EWG said "no, that language change could break compatibility". And possibly the proposal died on the vine.

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

In 2009, C++11 (then C++0x) was already behind schedule. As the proposition involved 300 changes to the library that (in theory) could cause regressions. No other reason was cited in the minutes. It being declined for not being worth the pain of regressions (or even checking for the frequency of regressions!) is understandable. So I wouldn't presume prejudice on the idea just because C++ rejected it in std.

这篇关于将赋值运算符标记为仅左值是否可以提高安全性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 18:58