【问题标题】:Are value parameters implicitly moved when returned by value?按值返回时,值参数是否隐式移动?
【发布时间】:2011-08-25 22:12:08
【问题描述】:

考虑以下函数:

Foo foo(Foo x)
{
    return x;
}

return x 会调用复制构造函数还是移动构造函数? (让我们把 NRVO 放在一边。)

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

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

如果在按值返回值参数时调用了移动构造函数,一切都应该没问题。但是当前的 g++ 编译器抱怨 return x 并带有以下错误消息:

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

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

【问题讨论】:

    标签: c++ rvalue-reference move-semantics c++11


    【解决方案1】:

    如果有 Foo 的移动 ctor,则应该选择它。

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

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

    但是,下一段明确地重新考虑了 move ctors:

    当满足或除了源对象是函数参数这一事实之外满足或将满足的条件,并且要复制的对象由左值指定时,首先执行重载决议以选择副本的构造函数就好像对象是由右值指定的。 …

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

    【讨论】:

    【解决方案2】:

    这是有效代码 - G++ 的行为不符合要求。 MSVC10 确实支持这种行为。

    【讨论】:

    • 虽然我尊重你的调查,但你不能证明这里的“有效”是正当的。 MSVC 以松懈和允许标准禁止的一些(方便)失误而闻名(例如,在类主体中绑定非常量引用和专门化成员函数)。
    • @Matthieu:我没有说它有效因为 MSVC10 支持它。这是有效的,因为标准是这样说的。
    • 我明白了,但仍然没有理由:)
    • @Matthieu:这个问题没有要求标准报价,它要求是或否。
    猜你喜欢
    • 2020-06-06
    • 2019-06-19
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 2022-07-04
    • 1970-01-01
    • 2016-10-26
    • 1970-01-01
    相关资源
    最近更新 更多