【问题标题】:Does using std::move on pair.first invalidate pair.second?在 pair.first 上使用 std::move 是否会使 pair.second 无效?
【发布时间】:2016-03-24 08:37:30
【问题描述】:

目前我的项目中有以下代码:

std::vector<int> vectorOfFirsts;
std::set<double> setOfSeconds;
std::list<std::pair<int,double>> cachedList;
// do something to fill the list 
for (const auto& pair : cachedList)
{
   vectorOfFirsts.push_back(pair.first);
   setOfSeconds.insert(pair.second);
}

这个列表会很大,并且只需要填充向量和集合(即它的内容可以无效)。我现在的问题是,如果以下优化是个好主意:

 for (const auto& pair : cachedList)
 {
       vectorOfFirsts.push_back(std::move(pair.first));
       setOfSeconds.insert(std::move(pair.second));
 }

在 pair.first 上调用 std::move 会以某种方式使 pair.second 无效吗?这段代码会为循环提供任何加速吗?我知道填充向量/集合而不是列表可能是个好主意,但是列表是通过一些我无法控制/没有时间深入研究的遗留代码填充的。

【问题讨论】:

  • 首先,一般来说,你不能从const的东西移开
  • 仅供参考,您应该更喜欢std::move(pair).first。它更智能,因为它考虑了引用类型等。
  • 你对std::moveintdouble一无所获。无论如何,它是一个副本。
  • 另外,移动原始类型的尝试会退回到副本
  • @Stefan 如果您不再需要 cachedList 则可以,前提是您删除 const

标签: c++ move std-pair


【解决方案1】:

在 pair.first 上调用 std::move 会以某种方式使 pair.second 无效吗?

没有。 firstsecond 是完全不同的变量,恰好存在于某个类对象中。移动一个不会影响另一个。

这段代码会为循环提供任何加速吗?

这取决于类型。 move-ing 的重点是转移资源,基本上。由于这里的对是ints 和doubles,所以不涉及资源,所以没有什么可以转移的。如果它是一对矩阵类型和张量类型,每个类型都有一些内部动态分配的缓冲区,那么它可能会提高性能。

【讨论】:

  • @TonyD 非常感谢这一点。我完全同意您的出色措辞。
【解决方案2】:

停止。

花点时间思考一下这段代码。内嵌评论

// step one - iterate through cachedList, binding the dereferenced
// iterator to a CONST reference
for (const auto& pair : cachedList)
{
  // step 2 - use std::move to cast the l-value reference pair to an
  // r-value. This will have the type const <pairtype> &&. A const
  // r-value reference.
  // vector::push_back does not have an overload for const T&& (rightly)
  // so const T&& will decay to const T&. You will copy the object.
  vectorOfFirsts.push_back(std::move(pair.first));

  // ditto
  setOfSeconds.insert(std::move(pair.second));
 }

必须是:

for (auto& pair : cachedList)
{
  vectorOfFirsts.push_back(std::move(pair.first));
  setOfSeconds.insert(std::move(pair.second));
}

是的,这将成为对 move 的有效和合法使用。

【讨论】:

    猜你喜欢
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    相关资源
    最近更新 更多