Dan*_*rey 7 c++ operator-overloading rvalue-reference c++11
请考虑以下代码:
struct MyString
{
// some ctors
MyString& operator+=( const MyString& other ); // implemented correctly
};
MyString operator+( const MyString& lhs, const MyString& rhs )
{
MyString nrv( lhs );
nrv += rhs;
return nrv;
}
MyString&& operator+( MyString&& lhs, const MyString& rhs )
{
lhs += rhs;
return std::move( lhs ); // return the rvalue reference we received as a parameter!
}
Run Code Online (Sandbox Code Playgroud)
这适用于以下用例
MyString a, b, c; // initialized properly
MyString result = a + b + c;
Run Code Online (Sandbox Code Playgroud)
但它创造了一个悬垂的参考
const MyString& result = a + b + c;
Run Code Online (Sandbox Code Playgroud)
现在,我理解为什么会这样,以及如何修复它(返回一个ravlue而不是rvalue引用)但我认为如果有人写上面的代码看起来像是在寻找麻烦,这是一个使用错误.是否有任何"规范"的现实示例,其中上述运算符返回右值引用是一个问题?为什么我应该总是从运营商那里返回一个rvalue有什么令人信服的理由?
您正在寻找的示例是基于范围的for
声明:
MyString a, b, c;
for( MyCharacter mc : a + b + c ) { ... }
Run Code Online (Sandbox Code Playgroud)
在这种情况下,结果a + b + c
绑定到引用,但嵌套的临时(由a + b
rvalue引用生成并作为rvalue引用返回(a + b) + c
)在执行基于范围的for循环之前被销毁.
该标准定义了基于范围的for循环
6.5.4基于范围的语句[stmt.ranged]
1对于
for
表单的基于范围的声明
for (
for-range-declaration:
表达式)
语句让range-init等同于括号括起来的表达式
( expression )
以及基于范围
for
的表单声明
for (
for-range-declaration:
braced-init-list)
语句让range-init等同于braced-init-list.在每种情况下,基于范围的
for
陈述等同于Run Code Online (Sandbox Code Playgroud){ auto && __range = range-init; for ( auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }
请注意,auto && __range = range-init;
会延长临时从返回的寿命范围,初始化,但它并没有嵌套的临时的寿命延长内的范围,初始化.
你应该相信字符串自己的移动构造函数,而不是惹麻烦:
MyString operator+(MyString lhs, MyString rhs)
{
lhs += std::move(rhs);
return std::move(lhs);
}
Run Code Online (Sandbox Code Playgroud)
现在,这两个MyString x = a + b;
和MyString y = MyString("a") + MyString("b");
提高工作效率.
归档时间: |
|
查看次数: |
1153 次 |
最近记录: |