【问题标题】:Expensive to move types昂贵的移动类型
【发布时间】:2017-11-12 13:49:54
【问题描述】:

我正在阅读官方的 CPPCoreGuidelines 以正确理解什么时候依靠 RVO 可靠,什么时候不可靠。 在 F20 处写着:

如果一种类型的移动成本很高(例如,数组),请考虑 在免费存储上分配它并返回一个句柄(例如, unique_ptr),或将其传递给非常量目标对象的引用 填充(用作输出参数)

我知道非 STL 类型没有针对移动进行优化,但是我怎样才能轻松检测到移动成本高昂的其他类型,所以我不会在它们上使用 RVO?

【问题讨论】:

  • RVO 通常是一种优化。你为什么不想让它发挥作用?
  • “非 STL 类型未针对移动进行优化” - 除非您编写移动 c'tor/assignment 并且它具有运行时优势。如果可以的话,没有什么能阻止您优化您的类型以具有移动语义。

标签: c++ rvo


【解决方案1】:

您似乎误解了“RVO”是什么。 “RVO”代表“返回值优化”,它是一种编译器优化,可防止调用任何移动或复制构造函数。例如

std::vector<huge_thing> foo()
{
    std::vector<huge_thing> result{/* ... */};
    return result;
}

void bar()
{
    auto v = foo(); // (0)
}

任何体面的编译器都不会执行任何复制/移动操作,而只是在 (0) 处构造v。在 C++17 中,由于对 prvalues 的更改,这是强制


就昂贵的移动而言:当然,移动可能会有昂贵的类型 - 但我想不出任何移动会比副本更昂贵的例子。

因此:

  • 依赖 RVO,尤其是在 C++17 中 - 即使对于“移动成本高”的类型,这也不会产生任何成本。

  • 如果一个类型的移动成本很高,那么复制也很昂贵 - 所以你真的别无选择。重新设计您的代码,以便尽可能不需要复制/移动。

【讨论】:

  • F.20 真的是个坏建议吗?似乎他们在这里不考虑 RVO。他们对Package fill(); 说“差:大价值”,但由于 RVO,它一点也不差...
  • 我已经理解了 RVO 是什么,只是我在问题中表达的不是很清楚(英语不是我的母语)。也许我应该说“当我可以相信我的编译器会使用 RVO 时”。在 F20 示例中,函数中似乎不需要副本,那么当我可以将它作为函数引用返回时,为什么要“依赖”RVO?
  • 所以在 F.20 Bjarne/Herb 中明确表示不每次都返回副本而你说相反,只是每次都依赖 RVO...我有点困惑,抱歉 :)
  • @Taw - 不,他们说不要返回 arrays 昂贵的对象。这是一个具体的建议,而不是笼统的“不要return东西”。
猜你喜欢
  • 1970-01-01
  • 2011-12-06
  • 2016-10-28
  • 2011-09-27
  • 2013-03-29
  • 2018-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多