linux 无线网卡驱动桥转发,引用和完美转发

# 右值引用 移动语意

~~~

右值引用解决了左值引用无法传递临时对象和常引用传递的对象只读的问题. 右值引用允许传递一个可变的临时对象引用.

移动构造使用移动而非赋值语义完成构造过程, 主要用于解决函数返回值时的大量深拷贝开销.

#include

int main(void)

{

int a = 30;

int &b = a;

//int &&c = a; /* error 右值引用不能绑定到左值 */

//int &d = a * 2; /* erro a * 2 是一个右值 */

const int e = a * 2; /* const 的引用可以绑定到一个右值 */

int && f = a * 2; /* 右值引用可以绑定到右值 */

//int && g = f; /* error 不能将一个右值引用绑定到一个变量上, 即使这个变量是右值引用类型也不行 */

int && h = std::move(f); /* ok */

return 0;

}

int r1 = 20;

int &&r2 = std::move(r1);

调用move就意味着承诺: 除了对r1赋值或销毁它以外, 将不能再使用它.

~~~

# 左值引用和右值引用

```

std::move(a) 返回变量右值

std::ref(a) 返回变量引用 主要是考虑函数式编程(如std::bind)在使用时,是对参数直接拷贝

```

# 完美转发

```

std::forward可以保存参数的左值或右值特性

```

# std::move()和std::forward()对比

* std::move执行到右值的无条件转换。就其本身而言,它没有move任何东西。

* std::forward只有在它的参数绑定到一个右值上的时候,它才转换它的参数到一个右值。

* std::move和std::forward只不过就是执行类型转换的两个函数;std::move没有move任何东西,std::forward没有转发任何东西。在运行期,它们没有做任何事情。它们没有产生需要执行的代码,一byte都没有。

* std::forward()不仅可以保持左值或者右值不变,同时还可以保持const、Lreference、Rreference、validate等属性不变;

```

#include

#include

#include

#include

using namespace std;

struct A

{

A(int&& n)

{

cout << "rvalue overload, n=" << n << endl;

}

A(int& n)

{

cout << "lvalue overload, n=" << n << endl;

}

};

class B

{

public:

template

B(T1 && t1, T2 && t2, T3 && t3) :

a1_(std::forward(t1)),

a2_(std::forward(t2)),

a3_(std::forward(t3))

{

}

private:

A a1_, a2_, a3_;

};

template

std::unique_ptr make_unique1(U&& u)

{

//return std::unique_ptr(new T(std::forward(u)));

return std::unique_ptr(new T(std::move(u)));

}

template

std::unique_ptr make_unique(U&&... u)

{

//return std::unique_ptr(new T(std::forward(u)...));

return std::unique_ptr(new T(std::move(u)...));

}

int main()

{

auto p1 = make_unique1(2);

int i = 10;

auto p2 = make_unique1(i);

int j = 100;

auto p3 = make_unique(i, 2, j);

return 0;

}

```

# C++中的万能引用和完美转发

1. 阅读这篇博文需要了解C++中的左值(lvalue)和右值(rvalue)的概念,详情参见我的另外一篇博文:[C++移动语义及拷贝优化](https://theonegis.github.io/cxx/C-%E7%A7%BB%E5%8A%A8%E8%AF%AD%E4%B9%89%E5%8F%8A%E6%8B%B7%E8%B4%9D%E4%BC%98%E5%8C%96/)

2. 万能引用和完美转发多涉及到模板的使用,如若不是自己写模板,则可不用关心

## 万能引用(Universal Reference)

首先,我们来看一个例子:

~~~javascript

#include

using std::cout;

using std::endl;

template

void func(T& param) {

cout << param << endl;

}

int main() {

int num = 2019;

func(num);

return 0;

}

~~~

这样例子的编译输出都没有什么问题,但是如果我们修改成下面的调用方式呢?

~~~javascript

int main() {

func(2019);

return 0;

}

~~~

则会得到一个大大的编译错误。因为上面的模板函数只能接受左值或者左值引用(左值一般是有名字的变量,可以取到地址的),我们当然可以重载一个接受右值的模板函数,如下也可以达到效果。

~~~javascript

template

void func(T& param) {

cout << "传入的是左值" << endl;

}

template

void func(T&& param) {

cout << "传入的是右值" << endl;

}

int main() {

int num = 2019;

func(num);

func(2019);

return 0;

}

~~~

输出结果:

~~~javascript

传入的是左值

传入的是右值

~~~

第一次函数调用的是左值得版本,第二次函数调用的是右值版本。但是,有没有办法只写一个模板函数即可以接收左值又可以接收右值呢?

C++ 11中有万能引用(Universal Reference)的概念:使用`T&&`类型的形参既能绑定右值,又能绑定左值。

但是注意了:**只有发生类型推导的时候,T&&才表示万能引用**;否则,表示右值引用。

所以,上面的案例我们可以修改为:

~~~javascript

template

void func(T&& param) {

cout << param << endl;

}

int main() {

int num = 2019;

func(num);

func(2019);

return 0;

}

~~~

## 引用折叠(Universal Collapse)

万能引用说完了,接着来聊引用折叠(Univers Collapse),因为完美转发(Perfect Forwarding)的概念涉及引用折叠。一个模板函数,根据定义的形参和传入的实参的类型,我们可以有下面四中组合:

* 左值-左值 T& & # 函数定义的形参类型是左值引用,传入的实参是左值引用

* 左值-右值 T& && # 函数定义的形参类型是左值引用,传入的实参是右值引用

* 右值-左值 T&& & # 函数定义的形参类型是右值引用,传入的实参是左值引用

* 右值-右值 T&& && # 函数定义的形参类型是右值引用,传入的实参是右值引用

但是C++中不允许对引用再进行引用,对于上述情况的处理有如下的规则:

所有的折叠引用最终都代表一个引用,要么是左值引用,要么是右值引用。规则是:**如果任一引用为左值引用,则结果为左值引用。否则(即两个都是右值引用),结果为右值引用**。

即就是前面三种情况代表的都是左值引用,而第四种代表的右值引用。

## 完美转发(Perfect Forwarding)

下面接着说完美转发(Perfect Forwarding),首先,看一个例子:

~~~javascript

#include

using std::cout;

using std::endl;

template

void func(T& param) {

cout << "传入的是左值" << endl;

}

template

void func(T&& param) {

cout << "传入的是右值" << endl;

}

template

void warp(T&& param) {

func(param);

}

int main() {

int num = 2019;

warp(num);

warp(2019);

return 0;

}

~~~

猜一下,上面的输出结果是什么?

~~~javascript

传入的是左值

传入的是左值

~~~

是不是和我们预期的不一样,下面我们来分析一下原因:

`warp()`函数本身的形参是一个万能引用,即可以接受左值又可以接受右值;第一个`warp()`函数调用实参是左值,所以,`warp()`函数中调用`func()`中传入的参数也应该是左值;第二个`warp()`函数调用实参是右值,根据上面所说的引用折叠规则,warp()`函数接收的参数类型是右值引用,那么为什么却调用了调用`func()的左值版本了呢?这是因为在`warp()`函数内部,左值引用类型变为了右值,因为参数有了名称,我们也通过变量名取得变量地址。

那么问题来了,怎么保持函数调用过程中,变量类型的不变呢?这就是我们所谓的“完美转发”技术,在C++11中通过`std::forward()`函数来实现。我们修改我们的`warp()`函数如下:

~~~javascript

template

void warp(T&& param) {

func(std::forward(param));

}

~~~

则可以输出预期的结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/327579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

虚拟机安装centeros7 无法连接网络 virsh命令找不到 删除多余的vir0 不然dubbo会有问题

进入linux ping www.baidu.com 无法访问 cd /etc/sysconfig/network-scripts vi ifcfg-ens33 修改这个文件 onbootyes 原来是on shutdown -h now 关机 然后重启虚拟机 再次ping ping www.baidu.com 就通了 https://www.zhihu.com/question/53708440 virsh命令找…

Java集合之EnumSet

转载自 Java集合之EnumSet EnumSet EnumSet 是一个专为枚举设计的集合类&#xff0c;EnumSet中的所有元素都必须是指定枚举类型的枚举值&#xff0c;该枚举类型在创建EnumSet时显式或隐式地指定。 EnumSet的集合元素也是有序的&#xff0c;EnumSet以枚举值在Enum类内的定义顺…

struts+hibernate+oracle+easyui实现lazyout组件的简单案例——OpSessionview实现

此过滤器的功能就是让Session始终保持着一个打开的状态&#xff1a; /** * Title: OpenSessionFilter.java * Package org.web * Description: TODO该方法的主要作用&#xff1a; * author A18ccms A18ccms_gmail_com * date 2017-4-19 下午6:51:37 * version V1.0 */ pa…

yaml配置文件整合Mybatis易错点

配置 mybatis:type-aliases-package: com.kuang.pojomapper-locations: classpath:mybatis/mapper/*.xml容易写成以下格式导致出错 mybatis:type-aliases-package: com.kuang.pojomapper-locations: classpath: mybatis/mapper/*.xml

Azure 部署 Asp.NET Core Web App

在云计算大行其道的时代&#xff0c;当你在部署一个网站时&#xff0c;第一选择肯定是各式各样的云端服务。那么究竟使用什么样的云端服务才能够以最快捷的方式部署一个 ASP.NET Core 的网站呢&#xff1f;Azure 的 Web App 服务是个很好的选择。 下面我们会通过 Visual Studio…

联想linux笔记本评测,联想(lenovo)G460AL-ITH Linux笔记本电脑CPU测试评测-ZOL中关村在线...

这颗英特尔最新的Core i5 430M双核心处理器基于32nm工艺&#xff0c;核心代号为Arrandate&#xff0c;主频为2.27GHz&#xff0c;共享的三级缓存为3MB。在开启睿频加速时&#xff0c;单核心的主频最高为2.53GHz&#xff0c;并且支持同步超线程技术。同时除了支持上一代处理器所…

SecureCRT连接Linux的操作步骤

https://www.cnblogs.com/Koma-vv/p/11100565.html SecureCRT连接Linux的操作步骤 虚拟机待机&#xff1a;Ctrlg进入 ipconfig是Windows里面的操作 ifconfig是Linux里面的操作 解决方法&#xff1a;右键&#xff1a; 打开终端是&#xff1a;在桌面上&#xff0c;鼠标右键才可…

聊聊并发(四)深入分析ConcurrentHashMap

转载自 聊聊并发&#xff08;四&#xff09;深入分析ConcurrentHashMap 术语定义 术语英文解释哈希算法hash algorithm是一种将任意内容的输入转换成相同长度输出的加密方式&#xff0c;其输出被称为哈希值。 哈希表hash table根据设定的哈希函数H(key)和处理冲突方法将一组…

struts+hibernate+oracle+easyui实现lazyout组件的简单案例——Jsp页面

由于要导入好多js文件和cs文件&#xff0c;并且每个页面都需要导入&#xff0c;所以我把公共的导入js和css文件放在了一个jsp里面&#xff0c;在用到的里面直接导入即可&#xff0c; 此项目用到的js文件下载&#xff1a;这里 用到的css文件的下载&#xff1a;这里 公共的导…

整合MyBatis---SpringBoot

整合MyBatis 官方文档&#xff1a;http://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/ Maven仓库地址&#xff1a;https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter/2.1.1 整合测试 1、导入 MyBatis 所需…

c语言 葬礼分号,其实从C语言用分号结尾开始,就是一个悲剧了……

……我该说啥好呢&#xff0c;不懂 pascal 的是你http://www.freepascal.org/docs-html/ref/refsu46.html#x138-14800013.2.1http://www.freepascal.org/docs-html/ref/refsu48.html#x140-15000013.2.3http://www.dragonkiller.nl/Delphi/delphi2009.html#StatementListpascal …

IDEA 底部工具栏没有 Version Control 解决办法

IDEA 底部工具栏没有 Version Control 解决办法 百度了半天 都说VCS配置不对 但是默认IDEA是配置好的 根本不需要修改 忽然看到 工具栏的快捷键 于是 Alt 9 就出现了 完美

一个基于Microsoft Azure、ASP.NET Core和Docker的博客系统

2008年11月&#xff0c;我在博客园开通了个人帐号&#xff0c;并在博客园发表了自己的第一篇博客。当然&#xff0c;我写博客也不是从2008年才开始的&#xff0c;在更早时候&#xff0c;也在CSDN和系统分析员协会&#xff08;之后名为“希赛网”&#xff09;个人空间发布过一些…

struts+hibernate+oracle+easyui实现lazyout组件的简单案例——Action的实现类

主要的业务操作都在这个struts的Action里面&#xff0c;大家来看看&#xff1a; /** * Title: EmpAction.java * Package org.web * Description: TODO该方法的主要作用&#xff1a; * author A18ccms A18ccms_gmail_com * date 2017-4-19 下午8:37:00 * version V1.0 */…

聊聊并发-Java中的Copy-On-Write容器

转载自 聊聊并发-Java中的Copy-On-Write容器 Copy-On-Write简称COW&#xff0c;是一种用于程序设计中的优化策略。其基本思路是&#xff0c;从一开始大家都在共享同一个内容&#xff0c;当某个人想要修改这个内容的时候&#xff0c;才会真正把内容Copy出去形成一个新的内容然后…

android 枚举类型比较大小写,Spring 3.0 MVC绑定枚举区分大小写

如果我有一个像这样的Spring控制器的RequestMapping ...RequestMapping(method RequestMethod.GET, value "{product}")public ModelAndView getPage(PathVariable Product product)产品是一个枚举。例如。 Product.Home当我请求该页面时&#xff0c;mysite.com/ho…

集成SpringSecurity---SpringBoot

集成SpringSecurity 安全简介 在 Web 开发中&#xff0c;安全一直是非常重要的一个方面。安全虽然属于应用的非功能性需求&#xff0c;但是应该在应用开发的初期就考虑进来。如果在应用开发的后期才考虑安全的问题&#xff0c;就可能陷入一个两难的境地&#xff1a;一方面&am…

OkHttp上传Json嵌套对象

public static DevInfoVo queryRCP() throws Exception {// 东八区时区Calendar cal Calendar.getInstance(TimeZone.getTimeZone("GMT8:00"));//JSONObject obj JSON.parseObject(JSON.toJSONString(pojo));JSONObject obj new JSONObject();obj.put("Autho…

大新闻!Magic Leap造假,HoloLens即将入华商用

昨天微软搞了大新闻&#xff0c;Terry和Alexi到了深圳&#xff0c;在WinHEC大会上宣布了2017上半年HoloLens正式入华商用。 而唯一竞争对手Magic Leap今天也被曝光其设备造假&#xff0c;各大科技媒体纷纷报道&#xff0c;部分相关报道如下&#xff1a; 【新浪科技】Magic Lea…

struts+hibernate+oracle+easyui实现lazyout组件的简单案例——struts.xml配置详情

最后我们来看一下struts.xml里面是怎么配置的呢&#xff0c; struts.xml: <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://strut…