请考虑以下代码:
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! }
这适用于以下用例
MyString a,b,c; // initialized properly MyString result = a + b + c;
但它创造了一个悬垂的参考
const MyString& result = a + b + c;
现在,我理解为什么会这样,以及如何修复它(返回一个ravlue而不是rvalue引用)但我认为如果有人写上面的代码看起来像是在寻找麻烦,这是一个使用错误.是否有任何“规范”的现实示例,其中上述运算符返回右值引用是一个问题?为什么我应该总是从操作符那里返回一个rvalue有什么令人信服的理由?
解决方法
您要查找的示例是基于范围的for语句:
MyString a,c; for( MyCharacter mc : a + b + c ) { ... }
在这种情况下,b c的结果绑定到引用,但嵌套的临时(由b生成并由(a b)c)返回为rvalue引用,在执行基于范围的for循环之前被销毁.
该标准定义了基于范围的for循环
6.5.4 The range-based for statement [stmt.ranged]
1 For a range-based
for
statement of the form
for (
for-range-declaration:
expression)
statementlet range-init be equivalent to the expression surrounded by parentheses
( expression )
and for a range-based
for
statement of the form
for (
for-range-declaration:
braced-init-list)
statementlet range-init be equivalent to the braced-init-list. In each case,a range-based
for
statement is equivalent to06001
请注意,汽车&& __range = range-init;会延长从range-init返回的临时值的生命周期,但它不会延长range-init中嵌套临时值的生命周期.