【问题标题】:move semantics std::move how use it移动语义 std::move 如何使用它
【发布时间】:2011-07-28 15:26:41
【问题描述】:
#include <type_traits>

template<class T>
typename std::remove_reference<T>::type&& move(T&& v)
{
    return v;
}

void main()
{
    int a;
    move(a);
}

为什么这段代码不能编译?

错误 C2440:'return':无法将 'int' 转换为 'int &&'

【问题讨论】:

  • 通过将move 应用于int 究竟想达到什么目的?
  • 是的,我不知道。这只是一个例子。但也许我的例子是错误的。
  • move semantics std::move的可能重复

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


【解决方案1】:

v 是返回语句中的左值(命名的右值引用是左值,出于安全原因),但move 的返回类型是右值引用(Tint&amp;,但你删除了参考,所以你在返回类型中形成类型int &amp;&amp;)。

你需要先static_castvremove_reference&lt;T&gt;::type &amp;&amp;创建一个未命名右值引用,当你想返回它时。

我不确定你的目标是什么。要么你想使用std::move(就像你在标题中说的那样),要么你想了解它是如何实现的(就像你展示的代码一样)。在不了解基本 C++ 规则的情况下尝试了解 std::move 的工作原理是没有意义的。我建议你看看我们的C++ Books List。在掌握了 C++ 之后,您可以了解 std::move 的工作原理。

【讨论】:

  • 未命名的右值引用也称为 xvalues ;)
  • 我查看了 gcc 中的std::move 实现,它的工作方式与@Guillaume07 所写的完全一样(没有static_cast)。所以你说这是一个错误?
  • @Ashot 我对 GCC 或 libstdc++ 的实现细节一无所知。我只知道显示的move实现是错误的。
  • @Ashot:也许你有一个旧版本的 gcc 仍然支持将右值引用绑定到左值?在 g++ 4.5.1 下编译失败:invalid initialization of reference...
  • @FredOverflow 看起来是的,我使用的是 gcc 4.4。现在要更新:)。谢谢
【解决方案2】:

这直接来自 C++0x 草案标准 (§20.2.3/6):

template &lt;class T&gt; typename remove_reference&lt;T&gt;::type&amp;&amp; move(T&amp;&amp; t) noexcept;

返回static_cast&lt;typename remove_reference&lt;T&gt;::type&amp;&amp;&gt;(t)

因此,如果您将 move 实现更改为以下内容,它就可以正常工作:

template<class T>
typename std::remove_reference<T>::type&& move(T&& v)
{
    return static_cast<typename std::remove_reference<T>::type&&>(v);
}

【讨论】:

    猜你喜欢
    • 2011-07-28
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-14
    • 1970-01-01
    • 2021-08-26
    相关资源
    最近更新 更多