当值被返回时,值参数是否隐式移动? [英] Are value parameters implicitly moved when returned by value?

查看:168
本文介绍了当值被返回时,值参数是否隐式移动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下函数:

  Foo foo(Foo x)
{
return x;
}

调用复制构造函数或move构造函数? (让我们把NRVO放在这里。)



为了研究,我写了一个简单的 Foo 类,不可复制:

  struct Foo 
{
Foo
Foo(const Foo&)= delete;
Foo(Foo&&)= default;
};

如果在按值返回值参数时调用move构造函数,但是当前的g ++编译器抱怨 return x 出现以下错误信息:

 错误:已删除的函数'Foo :: Foo(const Foo&)'

code>返回x 与返回std :: move(x),一切都很好。从这里我得出结论,如果需要,必须明确地从值参数移动。 g ++的行为是否符合?

解决方案

如果有Foo的move ctor,

函数参数在返回语句(FDIS§12.9p31,第一个项目符号)中从复制精确中显式排除:



  • 在具有类返回类型的函数中的返回语句中,当表达式是非易失性自动对象的名称(除了函数或catch子句参数)


然而,下一段明确地将move ctors考虑在内: / p>


当满足复制操作的限制条件或满足时,除非源对象是函数参数,并且要复制的对象由左值指定,重载分辨率选择该复制的构造函数首先执行,就像对象由右值指定。 ...


(Emphasis is mine in both quotes。)


Consider the following function:

Foo foo(Foo x)
{
    return x;
}

Will return x invoke the copy constructor or the move constructor? (Let's leave NRVO aside here.)

To investigate, I wrote a simple Foo class that is only movable but not copyable:

struct Foo
{
    Foo() = default;
    Foo(const Foo&) = delete;
    Foo(Foo&&) = default;
};

If the move constructor were invoked when returning value parameters by value, all should be fine. But the current g++ compiler complains about return x with the following error message:

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

If I replace return x with return std::move(x), everything is fine. From this I conclude that moving from value parameters must be done explicitly if desired. Is g++'s behavior conforming or not?

解决方案

If there is a move ctor for Foo, it should be selected.

Function parameters are explicitly excluded from copy elision in return statements (FDIS §12.9p31, first bullet):

  • in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter)

However, the next paragraph explicitly brings move ctors back into consideration:

When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. …

(Emphasis is mine in both quotes.)

这篇关于当值被返回时,值参数是否隐式移动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆