通过右值引用并使用std :: move()返回?

Art*_*zuk 2 c++ move-semantics c++11

考虑:

struct Foo {
    Foo ()                      { std::cout << "default ctor" << std::endl; }
    Foo (const Foo&)            { std::cout << "copy ctor" << std::endl; }
    Foo& operator= (const Foo&) { std::cout << "copy op" << std::endl; return *this; }
    Foo (Foo&&)                 { std::cout << "move ctor" << std::endl; }
    Foo& operator= (Foo&&)      { std::cout << "move op" << std::endl; return *this; }
    ~Foo ()                     { std::cout << "dtor" <<  std::endl; }
};


Foo process1 (Foo&& foo) {
    return foo;
}


Foo process2 (Foo&& foo) {
    return std::move (foo);
}
Run Code Online (Sandbox Code Playgroud)

和用法:

Foo foo {};
foo = process1 (std::move (foo));
Run Code Online (Sandbox Code Playgroud)

给出结果:

default ctor
copy ctor
move op
dtor
dtor
Run Code Online (Sandbox Code Playgroud)

和用法:

Foo foo {};
foo = process2 (std::move (foo));
Run Code Online (Sandbox Code Playgroud)

给出结果:

default ctor
move ctor
move op
dtor
dtor
Run Code Online (Sandbox Code Playgroud)

哪一个是首选的(process1或process2)?

这是否意味着在第一个例子(process1)中,如果我通过rvalue引用将对象传递给返回Object的函数,那么如果我不使用,将会复制该副本std::move()

编译:GCC 5.2.1

Ami*_*ory 6

在第一个版本中

Foo process1 (Foo&& foo) {
    return foo;
}
Run Code Online (Sandbox Code Playgroud)

您将其作为右值引用传递,但是通过"如果它具有名称"启发式,它被视为函数内的左值,因此复制ctor.

第二个版本"重新制作"这个rvalue使用std::move(这正是它的意思).因此避免了复制.

期望移动不会比副本更昂贵是非常合理的,因此,鉴于现实情况沸腾到此,您可能更喜欢第二个版本.