nos*_*sid 14 c++ operator-overloading assignment-operator c++11
最近,我跟着讨论了C++中表达式的赋值,如下例所示:
string s1, s2, s3;
(s1 + s2) = s3;
Run Code Online (Sandbox Code Playgroud)
使用C++ 11,可以将赋值运算符限制为左值引用(在左侧).当声明赋值运算符如下时,由于类型不兼容,编译器Clang拒绝带有错误消息的代码.
auto operator=(const string& rhs) & -> string&;
auto operator=(string&& rhs) & -> string&;
Run Code Online (Sandbox Code Playgroud)
我没有在任何地方见过这个.是否有充分的理由不为赋值运算符使用左值引用限定符(除了在大多数编译器中缺少支持)?
有趣!我甚至都没有意识到这一点并带我去寻找它(这是"向这个提议扩展移动语义"的一部分).符号在8.3.5 [dcl.decl]第4段中定义,以防任何人想要查看.
无论如何:现在,了解这个特性似乎最有用的是它用于重载,如果调用函数的对象是左值或右值,则可能表现不同.使用它来限制可以做的事情,例如,使用赋值的结果似乎是不必要的,特别是如果对象实际上恰好是左值.例如,您可能希望语法从分配给右值返回rvalue:
struct T {
auto operator=(T&) & -> T&;
auto operator=(T&&) & -> T&;
auto operator=(T&) && -> T;
auto operator=(T&&) && -> T;
};
Run Code Online (Sandbox Code Playgroud)
这里的意图是从分配结果中移除(不管是否值得,但我不确定:为什么不首先跳过作业?).我认为我不会主要使用此功能来限制使用.
就个人而言,我喜欢有时从rvalue获取左值的可能性,赋值运算符通常是一种方法.例如,如果你需要将一个左值传递给一个函数,但是你知道你不想对它使用任何东西,你可以使用赋值运算符来获得一个左值:
#include <vector>
void f(std::vector<int>&);
int main()
{
f(std::vector<int>() = std::vector<int>(10));
}
Run Code Online (Sandbox Code Playgroud)
这可能是滥用赋值运算符从rvalue获得左值,但不太可能偶然发生.因此,我不会通过限制赋值运算符仅适用于左值来使我的方式变得不可能.当然,将rvalue从赋值返回到rvalue也会阻止这种情况.如果有的话,两种用途中哪一种更有用,可能是一种考虑因素.
BTW,clang似乎支持自2.9版以来引用的语法.
是否有充分的理由不对赋值运算符使用左值引用限定符(除了大多数编译器中缺少支持)?
不,不是真的。使用左值或右值限定符为左值或右值对象构造正确的接口与使用相同const
,并且应该以相同的方式进行处理 - 每个函数都应该考虑限制。分配给右值实际上没有意义,因此应该禁止。
您没有看到它的原因主要是编译器支持不佳 - 右值引用*this
有点像thread_local
,大多数编译器实现者似乎已将其放在“从 C++11 实现的功能”堆栈的底部附近。