通过右值引用和 return 使用 std::move()?
Pass by rvalue reference and return using std::move()?
考虑:
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);
}
和用法:
Foo foo {};
foo = process1 (std::move (foo));
给出结果:
default ctor
copy ctor
move op
dtor
dtor
和用法:
Foo foo {};
foo = process2 (std::move (foo));
给出结果:
default ctor
move ctor
move op
dtor
dtor
哪个是首选(流程 1 或流程 2)?
这是否意味着在第一个示例 (process1) 中,如果我通过右值引用将对象传递给函数,returns 一个对象,如果我不使用 std::move()
?
编译器:GCC 5.2.1
第一个版本
Foo process1 (Foo&& foo) {
return foo;
}
您将它作为右值引用传递,但在 "if it has a name" heuristic 中,它在函数中被视为左值,因此是复制构造函数。
第二个版本 "remakes" 这是一个使用 std::move
的右值(这正是它的意思)。因此避免了复制构造函数。
预计移动不会比复制更昂贵,这是非常合理的,因此,考虑到现实生活中的情况,您可能更喜欢第二个版本。
考虑:
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);
}
和用法:
Foo foo {};
foo = process1 (std::move (foo));
给出结果:
default ctor
copy ctor
move op
dtor
dtor
和用法:
Foo foo {};
foo = process2 (std::move (foo));
给出结果:
default ctor
move ctor
move op
dtor
dtor
哪个是首选(流程 1 或流程 2)?
这是否意味着在第一个示例 (process1) 中,如果我通过右值引用将对象传递给函数,returns 一个对象,如果我不使用 std::move()
?
编译器:GCC 5.2.1
第一个版本
Foo process1 (Foo&& foo) {
return foo;
}
您将它作为右值引用传递,但在 "if it has a name" heuristic 中,它在函数中被视为左值,因此是复制构造函数。
第二个版本 "remakes" 这是一个使用 std::move
的右值(这正是它的意思)。因此避免了复制构造函数。
预计移动不会比复制更昂贵,这是非常合理的,因此,考虑到现实生活中的情况,您可能更喜欢第二个版本。