首页 >后端开发 >C++ >`std::move()` 如何实现 C 中左值到右值的转换?

`std::move()` 如何实现 C 中左值到右值的转换?

Linda Hamilton
Linda Hamilton原创
2024-11-21 08:14:09519浏览

How does `std::move()` achieve the conversion of lvalues to rvalues in C  ?

std::move 如何将表达式转换为右值?

std::move() 有助于将表达式转换为右值(右)值引用)以启用移动语义。然而,MSVC 标准库中的实现可能令人困惑。

实现如下:

template<class _Ty> inline
typename tr1::_Remove_reference<_Ty>::_Type&amp;&amp;
move(_Ty&amp;&amp; _Arg)
{ // forward _Arg as movable
    return ((typename tr1::_Remove_reference<_Ty>::_Type&amp;&amp;)_Arg);
}

让我们演示一下它是如何工作的:

Object obj1;
Object obj2 = std::move(obj1); // _Ty&amp;&amp; _Arg binds to obj1

调用 std::move(),_Arg 引用参数绑定到左值 obj1。但是,由于不允许直接将右值引用绑定到左值,因此可能需要强制转换为右值引用,例如 (Object&&)。

进一步深入研究 std:: 的实现remove_reference 澄清了问题:

template<class _Ty>
struct _Remove_reference
{ // remove reference
    typedef _Ty _Type;
};

template<class _Ty>
struct _Remove_reference<_Ty&amp;>
{ // remove reference
    typedef _Ty _Type;
};

template<class _Ty>
struct _Remove_reference<_Ty&amp;&amp;>
{ // remove rvalue reference
    typedef _Ty _Type;
};

此实现表明,remove_reference 将 T& 转换为 T,T&& 转换为 T,T&&& 转换为 T。因此,对于我们的情况,其中 obj1 是 Object 类型的左值,结果函数变为:

Object&amp;&amp; move(Object&amp; arg)
{
    return static_cast<Object&amp;&amp;>(arg);
}

进一步详细说明:

  • 当使用右值调用 move 时(例如 std::move(Object())),T 变为 Object,并且结果函数是:
Object&amp;&amp; move(Object&amp;&amp; arg)
{
    return static_cast<Object&amp;&amp;>(arg);
}

转换为 Object&& 是必要的,因为命名右值引用被视为左值,而不允许从左值到右值引用的隐式转换。

  • 当使用左值调用 move 时,如我们前面的示例所示,T 变为 Object&,结果函数为:
Object&amp;&amp; move(Object&amp; &amp;&amp; arg)
{
    return static_cast<Object&amp;&amp;>(arg);
}

这里,C 11 的引用折叠规则发挥作用并允许表达式 Object& && 被解释为 Object&,一个左值引用,它确实可以绑定到左值。因此,最终函数将其参数转换为右值引用并返回它。

总之,std::move() 利用 std::remove_reference 来实现左值和右值都转换为右值,从而方便移动C 中的语义。

以上是`std::move()` 如何实现 C 中左值到右值的转换?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn