c/c++ 右值引用,forward关键字
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关键字的更多相关文章
- c++ 右值引用,move关键字
c++ move关键字 move的由来:在 c++11 以前存在一个有趣的现象:T& 指向 lvalue (左传引用), const T& 既可以指向 lvalue 也可以指向 rv ...
- Item 25: 对右值引用使用std::move,对universal引用则使用std::forward
本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 右值引用只能绑定那些有资格被move的对象上去.如 ...
- 第16课 右值引用(3)_std::forward与完美转发
1. std::forward原型 template <typename T> T&& forward(typename std::remove_reference< ...
- C++11新特性之右值引用(&&)、移动语义(move)、完美转换(forward)
1. 右值引用 个人认为右值引用的目的主要是为了是减少内存拷贝,优化性能. 比如下面的代码: String Fun() { String str = "hello world"; ...
- 透彻理解C++11新特性:右值引用、std::move、std::forward
目录 浅拷贝.深拷贝 左值.右值 右值引用类型 强转右值 std::move 重新审视右值引用 右值引用类型和右值的关系 函数参数传递 函数返还值传递 万能引用 引用折叠 完美转发 std::forw ...
- C++ 右值引用与 const 关键字
C++11 新增了另一种引用:右值引用(rvalue reference),这种引用可指向右值,是使用 && 声明的.使用右值引用可以减少复制操作,延长临时对象生命周期,提升程序性能. ...
- [转载] C++11中的右值引用
C++11中的右值引用 May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移动语义std::move() 右值引用和右值的关系 完美转发 引用折叠推导 ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part8:Perfect Forwarding(完美转发):解决方案
本文为第八部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- C++11中的右值引用
原文出处:http://kuring.me/post/cpp11_right_reference May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移 ...
随机推荐
- [ArcGIS API for JavaScript 4.8] Sample Code-Get Started-layers简介
[官方文档:https://developers.arcgis.com/javascript/latest/sample-code/intro-layers/index.html] 一.Intro t ...
- Android之日志管理(Log)
##文章大纲一.为什么要使用日志管理工具二.日志管理工具实战三.项目源码下载 ##一.为什么要使用日志管理工具###1. 对IT安全至关重要 当您使用强大的日志管理软件自动触发以保护您的系统时,您已 ...
- BI基础知识
- 数据库常用操作SQL语句
禁用触发器: alter table tb disable trigger tir_name 启用触发器: alter table tb enable trigger tir_name
- 巧妙地使用typora编辑有道云笔记
设置方法 找到有道云笔记本地保存路径: 找到有道云笔记的保存的路径:启动有道云 - 设置 - 有道云笔记(本地文件) - 打开文件夹 使用typora打开有道云笔记目录: typora 菜单栏 - O ...
- 机器学习中如何处理不平衡数据(imbalanced data)?
推荐一篇英文的博客: 8 Tactics to Combat Imbalanced Classes in Your Machine Learning Dataset 1.不平衡数据集带来的影响 一个不 ...
- 我眼中的 Nginx(二):HTTP/2 dynamic table size update
张超:又拍云系统开发高级工程师,负责又拍云 CDN 平台相关组件的更新及维护.Github ID: tokers,活跃于 OpenResty 社区和 Nginx 邮件列表等开源社区,专注于服务端技术的 ...
- 【重学计算机】机组D6章:中央处理器
1. CPU的组成与功能 2. 数据通路 概念:执行部件间传送信息的路径,分共享通路(总线)和专用通路 抽象模型:时钟驱动下,A --> 组合逻辑 --> B D触发器定时模型: 时钟触发 ...
- 《代码整洁之道》(Clean Code)- 读书笔记
一.关于Bob大叔的Clean Code <代码整洁之道>主要讲述了一系列行之有效的整洁代码操作实践.软件质量,不但依赖于架构及项目管理,而且与代码质量紧密相关.这一点,无论是敏捷开发流派 ...
- Litepal【开源数据库ORM框架】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 好用的数据库框架. 效果图 代码分析 本篇主要是整理Litepal的引入和增删改查的简单操作,具体使用请阅读参考资料. 使用步骤 一 ...