在Stack Overflow回答here中,Kerrek发布以下代码。
Foo && g()
{
Foo y;
// return y; // error: cannot bind ‘Foo’ lvalue to ‘Foo&&’
return std::move(y); // OK type-wise (but undefined behaviour, thanks @GMNG)
}
GManNickG指出这会导致未定义的行为。
Kerrek添加
真;你真的不会回来&&从前进和移动的任何东西。 这是一个人为的例子。
令我困惑的是,C ++ 11标准使用函数调用,该函数调用返回一个右值引用作为xvalue表达式的示例。
xvalue(“eXpiring”值)也指对象,通常在附近 它的生命周期结束(以便它的资源可以被移动,因为 例)。 xvalue是某些表达式的结果 涉及右值参考(8.3.2)。 [例子:调用的结果 返回类型为右值引用的函数是xvalue。 -结束 例子]
那么什么时候确实在未定义的行为中返回rvalue引用结果呢?它是否总是导致未定义的行为,除了std::move
和std::forward
并且标准只是简洁?或者您是否必须访问未定义行为的返回值才能生成结果?
*当"当"我的意思是"在什么情况下"。我意识到这里没有有意义的时间概念。
答案 0 :(得分:8)
转换为引用不会延长局部变量的生命周期。
因此,在本地到期后使用对本地的引用是未定义的行为。
当函数完成时本地到期,无法使用返回值。
std::move
或std::forward
接受引用,并返回可能不同类型的引用。既不延长他们的辩论的生命周期,也不会返回对他们自己身体的本地变量的引用。
这里的UB不返回右值引用,而是返回基于对象的生命周期。它在使用时发生,而不是在施放或返回时发生。
也就是说,返回一个右值引用几乎不是一个好主意:返回一个副本。副本可以参与终身延期。例外情况是你写forward_as_tuple
之类的东西。