C++ 当值返回时,值参数是否隐式移动?

C++ 当值返回时,值参数是否隐式移动?,c++,rvalue-reference,move-semantics,c++11,C++,Rvalue Reference,Move Semantics,C++11,考虑以下功能: Foo foo(Foo x) { return x; } 将返回x调用复制构造函数还是移动构造函数?(让我们把NRVO放在一边。) 为了进行调查,我编写了一个简单的Foo类,它只能移动,不能复制: struct Foo { Foo() = default; Foo(const Foo&) = delete; Foo(Foo&&) = default; }; 如果在按值返回值参数时调用了move构造函数,则一切正常。但是当

考虑以下功能:

Foo foo(Foo x)
{
    return x;
}
将返回x
调用复制构造函数还是移动构造函数?(让我们把NRVO放在一边。)

为了进行调查,我编写了一个简单的
Foo
类,它只能移动,不能复制:

struct Foo
{
    Foo() = default;
    Foo(const Foo&) = delete;
    Foo(Foo&&) = default;
};
如果在按值返回值参数时调用了move构造函数,则一切正常。但是当前的g++编译器抱怨
返回x
,并显示以下错误消息:

error: deleted function 'Foo::Foo(const Foo&)'

如果我用
return std::move(x)
替换
return x
,一切都很好。由此我得出结论,如果需要,从值参数移动必须显式完成。g++的行为是否符合要求?

如果有一个用于Foo的move-ctor,那么应该选择它

返回语句中的复制省略明确排除了函数参数(FDIS§12.9p31,第一个项目符号):

  • 在具有类返回类型的函数中的return语句中,当表达式是非易失性自动对象的名称时(函数或catch子句参数除外)
但是,下一段明确将重新考虑移动系数:

当满足或将满足省略复制操作的标准时,除非源对象是函数参数,并且要复制的对象由左值指定,首先执行重载解析以选择副本的构造函数,就像对象由右值指定一样


(两个引号中的重点都是我的。)

这是有效的代码-G++的行为是不一致的。MSVC10确实支持这种行为。

。这是对草案的一个相对较晚的修改,这解释了为什么它还没有在所有地方实施。虽然我尊重你的调查,但你不能证明这里的“有效”。MSVC以其松散和允许一些标准禁止的(方便的)失误而闻名(例如绑定非常量引用和在类主体内专门化成员函数)。@Matthieu:我没有说它是有效的,因为MSVC10支持它。我明白了,但仍然没有理由:)@Matthieu:这个问题没有要求一个标准的引用,而是要求是或否。