当前位置: 首页 > news >正文

政府网站回复集镇建设规划/软文写作服务

政府网站回复集镇建设规划,软文写作服务,网站外链建设培训,dw网页制作超链接支持移动语义&#xff0c;是现代C的主要语言特性之一&#xff0c;std::move本质上就是把一个变量强转成右值引用。在gcc的源码中&#xff0c;std::move的实现如下&#xff1a; template<typename _Tp>_GLIBCXX_NODISCARDconstexpr typename std::remove_reference<_Tp…

支持移动语义,是现代C++的主要语言特性之一,std::move本质上就是把一个变量强转成右值引用。在gcc的源码中,std::move的实现如下:

  template<typename _Tp>_GLIBCXX_NODISCARDconstexpr typename std::remove_reference<_Tp>::type&&move(_Tp&& __t) noexcept{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }

通常,我们在程序中使用std::move都是为了触发移动构造函数或移动赋值运算符的调用,举个例子:

#include <string>int main()
{std::string str = "123";std::string str2 = std::move(str);return 0;
}

显然,通过std::move触发了移动构造函数。

如果等号的右侧是一个临时对象,则不需要调用std::move,这种场景,编译器会自动触发移动操作:

#include <string>int main()
{std::string str;str = std::string("123");return 0;
}

通过对应的汇编代码,我们确认,调用了std::string的移动赋值运算符:

.LC0:.string "123"
main:stp     x29, x30, [sp, -112]!mov     x29, spstr     x19, [sp, 16]add     x0, sp, 32bl      std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string() [complete object constructor]add     x0, sp, 96str     x0, [sp, 104]nopnopadd     x0, sp, 96add     x3, sp, 64mov     x2, x0adrp    x0, .LC0add     x1, x0, :lo12:.LC0mov     x0, x3bl      std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) [complete object constructor]add     x1, sp, 64add     x0, sp, 32bl      std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&)

原因其实也容易理解,临时对象就是右值,编译器对于右值的处理方式,就是调用移动构造函数或者移动赋值运算符。

如果一个函数的传入参数是常量,则调用std::move将无法触发移动构造:

#include <string>int main()
{const std::string str = "123";std::string str2 = std::move(str);return 0;
}

这种场景下,编译器生成代码实际上调用的是std::string的拷贝构造函数:

.LC0:.string "123"
main:stp     x29, x30, [sp, -112]!mov     x29, spstr     x19, [sp, 16]add     x0, sp, 96str     x0, [sp, 104]nopnopadd     x0, sp, 96add     x3, sp, 64mov     x2, x0adrp    x0, .LC0add     x1, x0, :lo12:.LC0mov     x0, x3bl      std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) [complete object constructor]add     x0, sp, 96bl      std::__new_allocator<char>::~__new_allocator() [base object destructor]nopadd     x0, sp, 64bl      std::remove_reference<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::type&& std::move<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)mov     x1, x0add     x0, sp, 32bl      std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [complete object constructor]mov     w19, 0add     x0, sp, 32bl      std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() [complete object destructor]add     x0, sp, 64bl      std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() [complete object destructor]mov     w0, w19b       .L7mov     x19, x0add     x0, sp, 96bl      std::__new_allocator<char>::~__new_allocator() [base object destructor]nopmov     x0, x19bl      _Unwind_Resumemov     x19, x0add     x0, sp, 64bl      std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() [complete object destructor]mov     x0, x19bl      _Unwind_Resume
.L7:ldr     x19, [sp, 16]ldp     x29, x30, [sp], 112ret
DW.ref.__gxx_personality_v0:.xword  __gxx_personality_v0

这个也容易理解,移动构造函数可能会修改入参,因为定义为常量,不能修改,所以不能调用移动构造函数,但是拷贝构造函数的入参是可以接受常量的。实际上std::move的类型强转是成功的,转型的结果就是常量右值引用:

#include <string>
#include <iostream>template<typename T> void f(T&& param) // universal reference
{using ParamType = T&&;bool isCnstRValRef = std::is_same<ParamType, const std::string&&>::value;if (isCnstRValRef) {std::cout << "param's type is const std::string&&\n";} else {std::cout << "param's type is other type\n";}
}int main()
{const std::string str = "123";f(std::move(str));std::string str2 = std::move(str);return 0;
}

测试结果就是const std::string&&:

[root@192 moderncpp]# ./test_move
param's type is const std::string&&

总结一下:

使用std::move就是为了把入参强转为右值,通常这样做是为了触发移动构造函数的调用,大部分场景都是OK的,但是,如果入参是常量,不要加std::move,因为加了也不会调用移动构造函数;如果入参是临时对象,也不要加std::move,因为不加也会调用移动构造函数。

参考资料:

《Effective Modern C++》

《C++并发编程实战》

http://www.jmfq.cn/news/4737007.html

相关文章:

  • 网站运营工作计划/seo官网优化详细方法
  • 企业网站建设美丽/北京seo优化
  • 自定义网站建设/快速排名优化seo
  • 深圳市专业做网站/精准客户信息一条多少钱
  • 网易做相册的网站/网络平台推广运营公司
  • 用什么编程语言做网站好/seo交流论坛seo顾问
  • 南京做网站建设/今日国际新闻最新消息事件
  • 郑州男科医院排名最好的医院/绍兴百度seo排名
  • 新余专业做淘宝网站/东莞网站关键词优化公司
  • 纯静态网站 维护/全国疫情最新情况公布
  • 公司用dw做网站吗/百度网盘怎么用
  • 网站建设开发定制/推广公司app主要做什么
  • 宁波外贸网站设计公司/网站模板平台
  • 域名做非法网站/营销推广网站推广方案
  • 方案库网站/免费行情软件app网站下载大全
  • 织梦网站后台如何做百度优化/今日最新消息
  • 100个免费推广网站的排名/买淘宝店铺多少钱一个
  • 廊坊网站制作建设/旅游产品推广有哪些渠道
  • wordpress弹窗登入/绍兴seo推广
  • 网站备案情况查询/网上推广企业
  • 惠州的企业网站建设/seo优化网
  • 一个公司的网站怎么做的/营销网站建设流程
  • 网站title如何修改/提交百度一下
  • 可做产品预售的网站/seo基础教程
  • linux 转换wordpress/安卓优化清理大师
  • 公司网站banner怎么做/苏州企业网站关键词优化
  • 丰台周边网站建设/丹东seo推广优化报价
  • 导航网站超链接如何做/搜索引擎调价工具哪个好
  • 东莞建站模板/百度信息流广告投放
  • 大石桥网站/关键词优化举例