【问题标题】:Forward or Move前进或移动
【发布时间】:2013-04-15 11:53:19
【问题描述】:

这些是移动和前进的有效用法吗?
f3 和 f4 是一样的吗?
这样做有危险吗?
谢谢!

#include <utility>
class A {};
A f1() {
  A a;
  return a;   // Move constructor is called
}
A f2(A&& a) {
  return a;   // Copy constructor is called, which is what I try to avoid.
}
A f3(A&& a) {
  return std::forward<A&&>(a); // Move constructor is called
}
A f4(A&& a) {
  return std::move(a); // Move constructor is called
}

【问题讨论】:

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


    【解决方案1】:
    • std::forward通用引用一起使用,即template &lt;typename T&gt; ... T&amp;&amp;

    • std::move右值引用一起使用(如您的A&amp;&amp;)。

    所以f1f4 都是可行的解决方案。他们做不同的事情,所以你必须决定你想要哪一个。

    不要使用f2f3

    【讨论】:

      【解决方案2】:

      std::forward 的存在是因为 &amp;&amp; 在类型推导下的工作方式存在一个怪癖。

      在类型推导下,T&amp;&amp; 中的 T 将绑定到 3 种可能性之一。如果从左值int&amp; 推导出来,T 将绑定到int&amp;。那么int&amp; &amp;&amp; 只是一个int&amp;。如果从左值int const&amp; 推导出来,T 将绑定到int const&amp;,并且int const&amp; &amp;&amp;int const&amp;。如果从某种右值int 推导出来,T 将绑定到int,而int&amp;&amp;int&amp;&amp;

      std::forward 是一个用于反转该映射的实用函数。 std::forward&lt;&gt;的三个相关签名分别是:T&amp; std::forward&lt;T&amp;&gt;(T&amp;)T const&amp; std::forward&lt;T const&amp;&gt;(T const&amp;)T&amp;&amp; std::forward&lt;T&gt;(T&amp;&amp;)

      在执行称为“完美转发”的技术时,所有这些最终都非常有用,您在类型推导上下文中使用 T&amp;&amp;t,然后使用 std::forward&lt;T&gt;(t) 传递从推导的“相同类型”到另一个电话。

      请注意,上面有一些简化的谎言。例如,T const&amp;&amp; 也有可能在类型方面非常晦涩难懂。我可能忽略了类型推导如何工作的一些细节,而术语 rvaluelvalue 并没有完全反映 C++11 中完整的 5 倍(或者是 6 倍?)不同类型的变量值.

      【讨论】:

        【解决方案3】:

        对于你的例子,他们会做同样的事情,但使用std::move 是惯用的

        A f(A&& a) {
          // use std::move(a)
        }
        

        函数模板稍有不同

        template<typename A>
        A f(A&& a) {
           // use std::forward<A>(a)
        }
        

        不同之处在于第二个版本可以同时接收左值和右值(Scott Meyers 将它们命名为“universal references”),而第一个版本只能接收右值。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-04-20
          • 2012-11-01
          • 1970-01-01
          • 2014-11-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多