我是靠谱客的博主 高兴面包,最近开发中收集的这篇文章主要介绍std::move()源码分析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

https://segmentfault.com/a/1190000020744971?utm_source=tag-newest

 

C++11 引入右值和移动语义,其中std::move()是不可或缺的。现在我们才看看std::move()是这么实现的。

remove_reference

在分析std::move()之前,先看看remove_reference,下面是remove_reference的实现:

template <class T>
struct remove_reference {
    using type = T;
};

// 特化版本
template <class T>
struct remove_reference<T&> {
    using type = T;
};

template <class T>
struct remove_reference<T&&> {
    using type = T;
};

remove_reference的作用是去除T中的引用部分,只获取其中的类型部分。无论T是左值还是右值,最后只获取它的类型部分。

std::move() 实现

借助remove_referencestd::move()的实现如下:

template <class T>
typename tinySTL::remove_reference<T>::type&& move(T&& t) noexcept {
        using return_type = typename tinySTL::remove_reference<T>::type&&;
        return static_cast<return_type>(t);
    }

在这段实现看来,实际上std::move并没有做什么工作,只是做了类型转换,将t转化为右值。

t 为右值

t为右值时,甚至都可以不用做类型转换,直接返回即可。

t 为左值

t为左值的时候,可以作为参数传进std::move()吗?可以的,因为如果一个函数模板参数类型为T&&,其中T是需要推到的类型,那么T&&表示万能引用。万能引用实际用到的技术是引用折叠。
引用折叠的规则可以概括为:

  • X& &、X& && 和 X&& & 折叠成 X&;
  • X&& && 折叠成 X&&。

如果T = X&是左值引用,则展开后得到了X& &&,根据上面的规则,最终得到X&
如果T = X&&是右值引用,则展开后得到了X& &&,根据上面的规则,最终得到X&&

所以,当t为左值或者左值引用时,进过引用折叠,得到的类型是T&。最后就是将左值转换为右值并返回了。

总结

实际上,std::move()并不会move,仅仅做了类型转换而已。真正的移动操作是在移动构造函数或者移动赋值操作符中发生的。
std::move()可以应用于左值,但这么做要谨慎。因为一旦“移动”了左值,就表示当前的值不再需要了,如果后续使用了该值,产生的行为是未定义。

 

 

 

最后

以上就是高兴面包为你收集整理的std::move()源码分析的全部内容,希望文章能够帮你解决std::move()源码分析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(35)

评论列表共有 0 条评论

立即
投稿
返回
顶部