【问题标题】:Should I use std::move on functions returning std::vector? [duplicate]我应该在返回 std::vector 的函数上使用 std::move 吗? [复制]
【发布时间】:2015-06-04 23:26:44
【问题描述】:

考虑这种函数:

std::vector<int> generateVector() {
    return std::vector<int>(10, 0);
}

像这样调用 generateVector() 有什么好处吗:

std::vector<int> v = std::move(generateVector());

..或者这种移动优化现在由编译器自动完成?

【问题讨论】:

  • 问问自己为什么它们被称为右值引用!!
  • 好的,现在我已经问过自己了。正如斯科特迈耶斯认为你应该使用 int x = std::move(y) 我真的很困惑,因此这个问题。我看不出这些案例之间的区别。这不是重复,在那个“可能重复”的问题中是完全不同的场景。
  • @user2061057 or is this kind of a move optimization now automatically done by the compiler?。重复的答案指出:所有返回值都已移动或优化,因此无需显式移动返回值。这不是对您问题的直接回答吗?这怎么不是重复的?
  • 我们是在谈论重复的答案还是重复的问题?问题不同,std::move 的使用方式也不同。
  • 如果它让您满意,我仍然可以将其标记为重复。

标签: c++ c++11 move-semantics


【解决方案1】:

std::move 的目的是将左值变成右值。在您的情况下,generateVector() 已经是一个右值,所以它是多余的。

【讨论】:

  • 不会说它是 "redundant"(这意味着它根本没有效果,这可能是错误的)。我宁愿说它可能会阻止某些优化,例如移动省略。所以更好不写std::move
【解决方案2】:

返回一个对象的函数调用的结果已经是一个右值,所以应用std::move没有任何好处。

事实上这可能是一种悲观:没有std::move,变量是直接从临时初始化的,所以临时(和移动)可以被省略。

【讨论】:

    【解决方案3】:

    都不是:

    • 没有任何好处。

    • 除了编译 C++ 之外,编译器没有做任何特别的事情。它可能会尽力做到这一点。

    幸运的是,表达式generateVector() 已经是一个右值,所以v 将使用移动构造函数构造,但实际上您的v 声明和generateVector 的定义会受到复制省略,所以该构造可以被视为等同于:

    std::vector<int> v(10, 0);
    

    换句话说,语言规则明确允许在这些情况下不调用复制构造函数,即使它们有副作用。

    【讨论】:

    • 之前在这里讨论过这个话题,我记得当时有人认为使用 std::move 会使代码变得更糟,因为就性能而言,复制省略比移动构造更可取。
    • @user2225104:我认为这仅指返回语句。 IE。 return std::move(std::vector&lt;int&gt;(10, 0)); 将是一个严格的悲观主义。
    猜你喜欢
    • 2017-10-19
    • 2016-03-09
    • 2019-07-09
    • 2013-03-20
    • 2017-07-24
    • 2013-08-06
    相关资源
    最近更新 更多