c++ forward关键字

forward的由来:模板函数中的推导类型,作为另一函数的参数时,不管实参是什么类型,作为另一个参数的实参时,都变成了左值。因为C++里规定函数的形参就是左值,不过调用侧的实参是否是右值。所以,调用的另一个函数的形参即使用T&& arg来声明,传过去的也是左值,编译不过,因为不能自动把左值转化成右值,除非使用std::move。forward就是为了解决这个问题的。

forward() 函数的作用:保持住实参的类型。
include <iostream>
using namespace std; void rvalue_call(int& v){
cout << "& call" << endl;
}
void rvalue_call(int&& v){
cout << "&& call" << endl;
}
void rvalue_call(const int& v){
cout << "const & call" << endl;
}
void rvalue_call(const int&& v){
cout << "const && call" << endl;
} template<typename T>
void func(T&& a){
rvalue_call(a);
} int main(void){
int x = 1;
func(x);//实参为左值
int& y = x;
func(y);//实参为左值引用
func(std::move(y));//实参为右值引用
func(100);//实参为右值引用
const int a = 11;
func(a);//实参为左值常引用
func(std::move(a));//实参为右值常引用
}

执行结果:

& call
& call
& call
& call
const & call
const & call

上面的例子即使传递的是右值,但也不能够调用到

void rvalue_call(int&& v)
void rvalue_call(const int&& v)

解决办法:加std::forward

#include <iostream>
using namespace std; void rvalue_call(int& v){
cout << "& call" << endl;
}
void rvalue_call(int&& v){
cout << "&& call" << endl;
}
void rvalue_call(const int& v){
cout << "const & call" << endl;
}
void rvalue_call(const int&& v){
cout << "const && call" << endl;
} template<typename T>
void func(T&& a){
rvalue_call(std::forward<T> (a));
} int main(void){
int x = 1;
func(x);//实参为左值
int& y = x;
func(y);//实参为左值引用
func(std::move(y));//实参为右值引用
func(100); const int a = 11;
func(a);
func(std::move(a));
}

执行结果:发现可以调用到右值的两个函数。这就是std::forward函数在模板里的作用

& call
& call
&& call
&& call
const & call
const && call

另一个例子:

#include <iostream>
#include <utility> template<typename F, typename T1, typename T2>
void fcn2(F f, T1&& t1, T2&& t2){
f(std::forward<T2>(t2), std::forward<T1>(t1));//OK
//f(std::move(t2), std::forward<T1>(t1));//OK
//f(t2, t1);//ERROR
} void f1(int&& i1, int& i2){
i1 = 10;
i2 = 20;
} int main(){
int i1 = 1, i2 = 2;
int& a = i1;
int& b = i2;
int&& c = 111; fcn2(f1, i1, 42);//因为42为右值,所以fcn2的T2为右值,如果不加forward,把T2的形参传给另一个函数时,它就变成了左值,但是函数f1的参数时右值,这时,编译就不过了。
std::cout << i1 << ", " << i2 << std::endl; }

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

c/c++ 右值引用,forward关键字的更多相关文章

  1. c++ 右值引用,move关键字

    c++ move关键字 move的由来:在 c++11 以前存在一个有趣的现象:T&  指向 lvalue (左传引用), const T& 既可以指向 lvalue 也可以指向 rv ...

  2. Item 25: 对右值引用使用std::move,对universal引用则使用std::forward

    本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 右值引用只能绑定那些有资格被move的对象上去.如 ...

  3. 第16课 右值引用(3)_std::forward与完美转发

    1. std::forward原型 template <typename T> T&& forward(typename std::remove_reference< ...

  4. C++11新特性之右值引用(&&)、移动语义(move)、完美转换(forward)

    1. 右值引用 个人认为右值引用的目的主要是为了是减少内存拷贝,优化性能. 比如下面的代码: String Fun() { String str = "hello world"; ...

  5. 透彻理解C++11新特性:右值引用、std::move、std::forward

    目录 浅拷贝.深拷贝 左值.右值 右值引用类型 强转右值 std::move 重新审视右值引用 右值引用类型和右值的关系 函数参数传递 函数返还值传递 万能引用 引用折叠 完美转发 std::forw ...

  6. C++ 右值引用与 const 关键字

    C++11 新增了另一种引用:右值引用(rvalue reference),这种引用可指向右值,是使用 && 声明的.使用右值引用可以减少复制操作,延长临时对象生命周期,提升程序性能. ...

  7. [转载] C++11中的右值引用

    C++11中的右值引用 May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移动语义std::move() 右值引用和右值的关系 完美转发 引用折叠推导 ...

  8. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part8:Perfect Forwarding(完美转发):解决方案

    本文为第八部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...

  9. C++11中的右值引用

    原文出处:http://kuring.me/post/cpp11_right_reference May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移 ...

随机推荐

  1. Android开发利器之stetho

    文章同步自javaexception Stetho是什么? github上地址https://github.com/facebook/stetho stetho是facebook出品的一款开发调试工具 ...

  2. SVN使用规范

    1.提交之前先更新.当完成功能之后,首先检查自己修改了什么 ,然后通过编译并且自己测试之后,谨慎地提交,不可强行提交. 2.在更新时注意所更新文件的列表,如果提交过程中产生了更新,也需要重新编译并且完 ...

  3. Vagrant 构建 Linux 开发环境

    Vagrant 是一个简单易用的部署工具,用英文说应该是 Orchestration Tool .它能帮助开发人员迅速的构建一个开发环境,帮助测试人员构建测试环境, Vagrant 基于 Ruby 开 ...

  4. python 简史

    ---恢复内容开始--- Python的作者,Guido von Rossum,确实是荷兰人.1982年,Guido从阿姆斯特丹大学(University of Amsterdam)获得了数学和计算机 ...

  5. 通信(二):进程间通信之socket

    一.为什么要学习socket? 我们打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?我们用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket.本地的进程间通 ...

  6. 自学python的日记分享

    2019.4.22登记 课堂笔记 2019.4.8 在windows环境下,用python写出第一个程序“hello world” print("Hello World!!!") ...

  7. PS抠图简单粗暴2种方法

    1.矩形框住要抠的→ Ctrl+j →选中图层 →矩形框住 →图像裁剪另存为 2.钢笔工具框住要抠的→ Ctrl+Enter→ Ctrl+j→.钢笔框住→图像裁剪另存为

  8. [Nuget]Nuget命令行工具安装

    下载 地址:https://www.nuget.org/downloads 直接下最新推荐版本(recommended latest)就好了. 是个单一的nuget.exe文件. 安装配置 想要在wi ...

  9. 每日分享!~ JavaScript中面试基础--1,数组检测的方式 2.传统事件绑定和W3C标准绑定事件的区别~

    javaScript 那些方式中检测数据类型 typeof typeof isNaN // 结果是function 检测数组的几种方式 instanceof arr instanceof Array( ...

  10. windows安装IDEA

    1.安装下载 https://www.jetbrains.com/idea/download/#section=windows 2.服务器激活地址: 39.129.9.34:8888 https:// ...