C++ 11本地命名引用返回值(xvalue)?

And*_*zos 4 c++ c++11

我们有以下类型X和功能f:

struct X { ... };

X f() { ... };
Run Code Online (Sandbox Code Playgroud)

现在考虑另一个函数的三个替代定义g:

(1)

void g()
{
    X x = f();

    ...
}
Run Code Online (Sandbox Code Playgroud)

(2)

void g()
{
    X& x = f();

    ...
}
Run Code Online (Sandbox Code Playgroud)

(3)

void g()
{
    X&& x = f();

    ...
}
Run Code Online (Sandbox Code Playgroud)

三种不同情况之间定义的行为(或潜在行为)有何不同?(假设三个案例中的占位符'...'代码相同)

更新:

如果g退回如果X:以下是合法且正确的吗?

X g()
{
    X&& x = f();

    ...

    return move(x);
}
Run Code Online (Sandbox Code Playgroud)

(移动是否必要,是否有任何作用?)

您是否期望RVO链接以便下面会产生相同的代码?

X g()
{
    X x = f();

    ...

    return x;
}
Run Code Online (Sandbox Code Playgroud)

Pup*_*ppy 6

2是非法的.另外两个基本相同 - x是一个可变的左值类型,X它的生命在g()返回时结束.

当然,严格来说,第一个调用移动构造函数(但是一些RVO/NRVO操作的主要候选者)而第三个不调用,所以如果X是不可移动的(非常奇怪的......)第三种情况是合法的但是第一种情况不是,第一个可能更贵.然而,编译器opts和不可移动类型的现实是,这几乎完全是技术性的,如果你真的可以证明任何这样的情况,我会感到惊讶.