我有一个非常基本的问题:使用std::vector<A>
返回std::move
是个好主意吗?例如:
class A {};
std::vector<A> && func() {
std::vector<A> v;
/* fill v */
return std::move(v);
}
我应该以这种方式返回std::map
,std::list
..等等吗?
答案 0 :(得分:12)
你声明一个函数通过r值引用返回 - 这几乎不应该完成(如果你通过引用返回本地对象,你最终会得到一个悬空引用)。而是声明函数按值返回。这样,调用者的值将由函数返回的r值构成。返回的值也将绑定到任何引用。
其次,不,你应该不使用显式std::move
返回,因为这会阻止编译器使用RVO。没有必要,因为编译器会自动将任何返回的l值引用转换为r值引用。
std::vector<A> func() {
std::vector<A> v;
/* fill v */
return v; // 'v' is converted to r-value and return value is move constructed.
}
答案 1 :(得分:1)
不,不是。事实上,这在某些情况下会阻止复制。某些编译器甚至会发出警告,称为-Wpessimizing-move
。
就像我之前写的答案一样,只需按值返回,将返回类型更改为std::vector<A>
,编译器将在需要时调用move构造函数。
你可以看一下我刚发现的这篇文章,它似乎更详细地解释了它(虽然我没有通过自己阅读): https://vmpstr.blogspot.hu/2015/12/redundant-stdmove.html
答案 2 :(得分:0)
启用优化的gcc和clang编译器在返回局部变量和编写std::move()
时都会为这两种情况生成相同的二进制代码。
只需返回一个值。
但是,如果您创建移动构造函数并为自定义类移动&&
,则使用noexcept
和operator=
说明符非常有用