<五>move移动语义和forward类型转发

move : 移动语义,得到右值类型
forward:类型转发,能够识别左值和右值类型

只有两种形式的引用,左值引用和右值引用,万能引用不是一种引用类型,它存在于模板的引用折叠情况,但是能够接受左值和右值
区分左值和右值得一个简单方式就是能不能取地址
一个右值一旦有名字那么就变成了左值

#include <iostream>
using namespace std;

void process(int & i) {
	std::cout << i << " lvalue" << std::endl;
}

void process(int && i) {
	std::cout << i << " r value" << std::endl;
}

template<typename T>
void test(T && v) { //这里的&& 表示万能引用,既能接受左值也能接受右值
	process(v);
}

int main() {

	int i = 100;
	test(i);
	test(200);

	system("pause");
	return 0;
}

<五>move移动语义和forward类型转发

上面的运行结果 我们发现 test(i); 和 test(200); 最后都调用了 void process(int & i) 左值形参,
test(T && v) 接受test(i)的时候,是用左值去接, 接受test(200)的时候,使用右值去接,
其中有一点右值本身是一个左值类型(如何理解?右值本身是有地址有名称的,所以他本身就可以取地址了,他是一个左值)
所以函数形参一定是个左值,他有名字,有空间了,变成了具名对象,200传过去后变成了一个左值.

200 传入 test后就变成了一个左值了,进入了test 函数后没有保留好原始信息,所以 process(v); 就都调用了void process(int & i) 左值形参,
这个我叫做 不完美转发

但是我希望 在test 函数内任然能够保留原始信息,原始的是左值继续保留左值,原始是右值就继续保留右值, 如何实现呢? 完美转发

引用折叠技术

形参 是 T && v ,在模板函数形参,两个引用 在一起会引发引用折叠, 有一个左值引用 最后是=》左值, 两个都是右值 最后是=>右值

即 test(i) + void test(T && v) => T & && i => 左值
即 test(200) + void test(T && v) => T && && 200 => 右值

所以将 函数形参写成 &&

//模板实例化过程中出现这种情况就会发生引用折叠,如果任一尹永伟左值引用,那么结果就是左值引用,
//如果两个都是右值引用,那么结果为右值引用
template<typename T>
void test2(T && v) {	
	std::cout  <<"is int &  " <<  std::is_same_v<T, int &> << std::endl;
	std::cout << "is int    " <<  std::is_same_v<T, int > << std::endl;
}

int main() {

	int i = 100;
	test2(i);
	test2(200);

	system("pause");
	return 0;
}

<五>move移动语义和forward类型转发

template<typename T>
void test2(T && v) {	
	std::cout  <<"is int &  "<< std::is_same_v<T, int &> << std::endl;
	std::cout << "is int    " << std::is_same_v<T, int > << std::endl;
}

int main() {

	int i = 100;
	test2(i);
	test2(200);

	system("pause");
	return 0;
}

test2(i) 调用模板会实例化出如下模板
void test2(int & && v) {	
	std::cout  <<"is int &  "<< std::is_same_v<T, int &> << std::endl;
	std::cout << "is int    " << std::is_same_v<T, int > << std::endl;
}

test2(200) 调用模板会实例化出如下模板
void test2(int && v) {	
	std::cout  <<"is int &  " << std::is_same_v<T, int &> << std::endl;
	std::cout << "is int    " << std::is_same_v<T, int > << std::endl;
}

上面两个实例化出来的模板,形参根据引用折叠技术 
void test2(int & && v) =》void test2(int & v)
void test2(int &&   v) =》void test2(int && v)


即 如果 test2(i)  那么模板中的 T  就是  int &
如果 test2(200 )  那么模板中的 T  就是  int


所以 下面的代码 
template<typename T>
void test(T && v) { //这里的&& 表示万能引用,既能接受左值也能接受右值
	process(v);
}

我们这里这么改一下
template<typename T>
void test(T && v) { //这里的&& 表示万能引用,既能接受左值也能接受右值      
	 
         process(static_cast<T&&>(v));
        // test(i)  => process( static_cast<int & &&>(v)); =>  process( static_cast<int & >(v));
        // test(200)=> process( static_cast<int &&>(v));   =>  process( static_cast<int && >(v));
}


原文链接:https://www.cnblogs.com/erichome/p/16942125.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:<五>move移动语义和forward类型转发 - Python技术站

(0)
上一篇 2023年5月3日
下一篇 2023年5月5日

相关文章

  • 【Visual Leak Detector】配置项 StackWalkMethod

    说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇介绍 VLD 配置文件中配置项 StackWalkMethod 的使用方法。同系列文章目录可见 《内存泄漏检测工具》目录 目录 说明 1. 配置文件使用说明 2. 设置调用堆栈的跟踪方法 2.1 测试代码 2.2 StackWalkMethod = fast 时的输出 2.3 StackWal…

    C++ 2023年4月18日
    00
  • C++/Qt网络通讯模块设计与实现(总结)

    至此,C++/Qt网络通讯模块设计与实现已分析完毕,代码已应用于实际产品中。 C++/Qt网络通讯模块设计与实现(一) 该章节从模块的功能需求以及非功能需求进行分析,即网络通讯模块负责网络数据包的发送、接收以及对外提供功能调用以及接口回调,其不进行产品业务的实现,达到平台化复用的目的,给出了类图,如下所示::   符合先设计再开发的思想,各类的功能也有详细描…

    C++ 2023年4月18日
    00
  • 2023.5.5 面向对象程序设计实验报告

    实验项目名称:模板 一、实验目的 1、熟练掌握函数模板和类模板的定义格式。 2、熟练运用函数模板和类模板解决实际问题。 二、实验内容 1、复数类Complex有两个数据成员:a和b, 分别代表复数的实部和虚部,并有若干构造函数和一个重载-(减号,用于计算两个复数的距离)的成员函数。 要求设计一个函数模板 template < class T > …

    C++ 2023年5月5日
    00
  • 非常可乐

    题目描述 大家一定觉得运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为\(S (S < 101)\)毫升 (正好装满一瓶) ,它们三个之间可…

    C++ 2023年4月27日
    00
  • Qt-FFmpeg开发-视频播放(5)

    音视频/FFmpeg #Qt Qt-FFmpeg开发-视频播放【软/硬解码 + OpenGL显示YUV/NV12】 目录 音视频/FFmpeg #Qt Qt-FFmpeg开发-视频播放【软/硬解码 + OpenGL显示YUV/NV12】 1、概述 2、实现效果 3、FFmpeg硬解码流程 4、优化av_hwframe_transfer_data()性能低问题…

    C++ 2023年4月17日
    00
  • 【Visual Leak Detector】在 VS 2015 中使用 VLD

    说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇介绍在 VS 2015 中使用 VLD。同系列文章目录可见 《内存泄漏检测工具》目录 目录 说明 1. 使用前的准备 3. 在 VS 2015 中使用 VLD 3.1 无内存泄漏时的输出报告 3.2 有内存泄漏时的输出报告 4. 无法正常使用的可能原因 1. 使用前的准备 参考本人另一篇博客 …

    C++ 2023年4月17日
    00
  • 2023团队天梯模拟赛 L2-3 智能护理中心统计 and L3-1 塔防游戏(23分)

    L2-3 智能护理中心统计 智能护理中心系统将辖下的护理点分属若干个大区,例如华东区、华北区等;每个大区又分若干个省来进行管理;省又分市,等等。我们将所有这些有管理或护理功能的单位称为“管理结点”。现在已知每位老人由唯一的一个管理结点负责,每个管理结点属于唯一的上级管理结点管辖。你需要实现一个功能,来统计任何一个管理结点所负责照看的老人的数量。 注意这是一个…

    C++ 2023年4月19日
    00
  • QML和QT

    推荐一些学习qml教程 Qt官方的QML教程: https://doc.qt.io/qt-5/qtqml-index.html这是一个由Qt官方提供的完整的QML教程,包含了所有基本知识和高级语法。 QML中文网:http://www.qmlcn.com/这是一个非常不错的中文QML学习网站,提供了丰富的例子和教程,而且有很多QML爱好者在这里交流。 《Qt…

    C++ 2023年4月18日
    00
合作推广
合作推广
分享本页
返回顶部