什么时候返回rvalue引用导致未定义的行为?

Pra*_*tic 3 c++ undefined-behavior rvalue-reference c++11

这里的Stack Overflow答案中,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)
}
Run Code Online (Sandbox Code Playgroud)

GManNickG指出这会导致未定义的行为.

克雷克补充道

真正; 除了前进和移动,你不会真正从任何东西返回&&.这是一个人为的例子.

令我困惑的是,C++ 11标准使用函数调用,该函数调用返回rvalue引用作为xvalue表达式的示例.

xvalue("eXpiring"值)也指对象,通常接近其生命周期的末尾(例如,可以移动其资源).xvalue是涉及rvalue引用的某些表达式的结果(8.3.2).[示例:调用返回类型为右值引用的函数的结果是xvalue. - 末端的例子]

那么,当确实在未定义的行为中返回rvalue引用结果时?是否总是导致未定义的行为,除了std::movestd::forward和标准只是简洁?或者您是否必须访问未定义行为的返回值才能生成结果?

*"何时"是指"在什么情况下".我意识到这里没有有意义的时间概念.

Yak*_*ont 8

转换为引用不会延长局部变量的生命周期.

因此,在本地过期后使用对本地的引用是未定义的行为.

由于本地函数完成时到期,因此无法使用返回值.

std::move或者std::forward获取引用,并返回可能不同类型的引用.既没有延长他们争论的生命周期,也没有返回对他们自己身体的本地变量的引用.

这里的UB不返回右值引用,而是返回基于对象的生命周期.它在使用时发生,而不是在施放或返回时发生.

也就是说,返回一个右值引用几乎不是一个好主意:返回一个副本.副本可以参与终身延期.例外情况是你写的东西forward_as_tuple.