c – 临时对象的子对象是否保证在返回时被移动?

前端之家收集整理的这篇文章主要介绍了c – 临时对象的子对象是否保证在返回时被移动?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
#include <string>
#include <vector>

using namespace std;

auto f()
{
    vector<string> coll{ "hello" };

    //
    // Must I use move(coll[0]) ?
    //
    return coll[0]; 
}

int main()
{
    auto s = f();
    DoSomething(s);
}

我知道:如果我只是返回coll,那么coll保证在返回时被移动.

不过,我不确定:coll [0]是否也保证在返回时被移动?

更新:

#include <iostream>

struct A
{
    A() { std::cout << "constructed\n"; }
    A(const A&) { std::cout << "copy-constructed\n"; }
    A(A&&) { std::cout << "move-constructed\n"; }
    ~A() { std::cout << "destructed\n"; }
};

struct B
{
    A a;
};

A f()
{
    B b;
    return b.a;
}

int main()
{
    f();
}

gcc 6.2和clang 3.8输出相同:

constructed

copy-constructed

destructed

destructed

解决方法

“隐性移动”规则的最干净的表述是目前工作文件[class.copy.elision]/3

In the following copy-initialization contexts,a move operation might@H_403_30@ be used instead of a copy operation:

  • If the expression in a return statement ([stmt.return]) is a (possibly parenthesized) id-expression that names an object with@H_403_30@ automatic storage duration declared in the body or@H_403_30@ parameter-declaration-clause of the innermost enclosing function or lambda-expression,or

  • […]

overload resolution to select the constructor for the copy is first@H_403_30@ performed as if the object were designated by an rvalue. If the first@H_403_30@ overload resolution fails or was not performed,or if the type of the@H_403_30@ first parameter of the selected constructor is not an rvalue reference@H_403_30@ to the object’s type (possibly cv-qualified),overload resolution is@H_403_30@ performed again,considering the object as an lvalue.

b.a和coll [0]都不是id表达式.所以没有隐含的动作.如果你想要一个举动,你必须明确地做.

猜你在找的C&C++相关文章