用std :: move返回std :: vector

时间:2017-05-19 09:05:03

标签: c++ return move

我有一个非常基本的问题:使用std::vector<A>返回std::move是个好主意吗?例如:

class A {};
std::vector<A> && func() {
    std::vector<A> v;
    /* fill v */
    return std::move(v);
}

我应该以这种方式返回std::mapstd::list ..等等吗?

3 个答案:

答案 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()时都会为这两种情况生成相同的二进制代码。 只需返回一个值。

但是,如果您创建移动构造函数并为自定义类移动&&,则使用noexceptoperator=说明符非常有用