C++11中的完美转发
创始人
2024-05-19 10:06:10
0

C++11中的完美转发

在讨论引用折叠这个话题之前,先回顾一下C++11中的引用,

在C++11中引用有4种:非常量左值引用非常量右值引用常量左值引用常量右值引用。其中常量右值引用没有应用价值,所以我们不考虑。

  1. 非常量左值引用只能绑定非常量左值
  2. 非常量右值引用只能绑定非常量右值
  3. 常量左值引用又称万能引用,他能绑定所有值,但是不能修改被绑定的值
  4. 常量右值引用能绑定右值,但是不能修改被绑定的值(没有实用价值)

我们在模板中经常会调用另一个模板函数或者函数,我们希望我们能够在传参时,减少临时对象的产生,即我们总是希望按照引用传参,这时我们就提出了完美转发的概念。

template 
void foo(T t)
{run(t);
}

1.引用折叠

typedef const int T;
typedef T& TR;
typedef TR&& TRRR;
TRRR&& a=1;

上面这段代码在C++98中是无法编译的, 而在C++11中却是可以通过的,TRRR &&的类型会被推导为const int &

下面给出具体的折叠规则:

typedef T& TR;
TR v;//T&
TR &v;//T&
TR && v;//T&typedef T&& TR;
TR v;//T&&
TR & v;//T&
TR && v;//T&&

即左值引用和右值引用在折叠的时候,优先折叠为左值引用

2.完美转发

#include
using namespace std;
void run(int &&m)
{cout<<"rvalue reference\n";
}
void run(int &m)
{cout<<"lvalue reference\n";
}void run(const int &m)
{cout<<"const lvalue reference\n";
}
void run(const int &&m)
{cout<<"const rvalue reference\n";
}template 
void foo( T &&t)
{run(static_cast(t));
}
int main()
{int a;foo(a);foo(move(a));const int b=1;foo(b);foo(move(b));}
lvalue reference
rvalue reference
const lvalue reference
const rvalue reference

我们看一下,这个模板函数foo中实现的就是完美转发

template 
void foo( T &&t)
{run(static_cast(t));
}

如果a是个X类型的左值,那么T会被推导为X&,则模板实例化为

void foo( X& && t)
{run(static_cast(t));
}

根据引用折叠理论,上面就会变成左值引用

而如果a是个右值,那么T就会被推导为X,则模板实例化为

void foo( X&& t)
{run(static_cast(t));
}

所以不管我们传递的是左值还是右值,run中都是按照引用传递的,这就是完美转发。实际上,真正奏效的是static_cast()函数,它根本解决的是右值引用本身是个左值,所以得把他转化成右值这件事,
我们会发现,它做的事情和std::move()是一样的事情,但是为了后续区分,我们一般实用forward()函数来代替static_cast
注意,move()forward()的区别在于,move是无条件转化为右值,而forward是当且仅当它是右值引用变成的,而且我们要提供模板参数T,用以告知参数的原来类型。

完美转发的应用在于包装函数

#include
using namespace std;void func1(int &&)
{cout<<"func1"<cout<<"func2"<
void foo( T &&t, U& func)
{func(forward(t));
}
int main()
{foo(1,func1);foo(2,func2);
}

上面这种设计就是封装多个函数为一个函数,在C++11中make_pairmake_unique都是用上面这种方式实现的

上一篇:Python调用lua

下一篇:TII投稿时间线

相关内容

热门资讯

特朗普签署税收和支出法案后 马...   埃隆·马斯克在其X社交平台上宣布,他一直威胁要成立的新政党“已经成立”。美国总统特朗普此前签署了...
时隔两年 三大运营商重启eSI... 格隆汇7月6日|据中国经营报,时隔两年,我国运营商的eSIM业务迎来重启。近日,中国联通携手中兴通讯...
不添麻烦的美 张雅怡 重庆市两江新区重光小学四(2)班 妈妈经常教导我“不给别人添麻烦”。如何才能不给别人...
媒体视角∣践行“三投资”理念、... (转自:国金证券第5小时)记者从上交所获悉,上交所于6月26日至27日联合重庆证监局、中金所、重庆市...
马斯克公布与特朗普闹翻原因 转自:北京日报客户端当地时间5日,美国亿万富翁埃隆·马斯克在社交媒体上宣布成立“美国党”,并回答网友...
第28届澳门书市嘉年华汇聚万种... 来源:海外网海外网澳门7月5日电(记者富子梅)以“东亚文化‧世界异彩”为主题的“第28届澳门书市嘉年...
台风“丹娜丝”或再加强,广东高... 转自:大湾区之声中央气象台7月6日10时继续发布台风黄色预警:今年第4号台风“丹娜丝”的中心今天(6...
云南省城市环境空气质量预报(7... 昆明信息港讯 机器人小明 7月7日,昆明、玉溪、楚雄、曲靖、昭通、蒙自、文山、保山、芒市、大理、丽江...
存安全隐患!罗马仕、安克召回充... 近期,罗马仕、安克创新两家公司相继宣布召回多款充电宝产品,涉及召回数量超过120万台,民航局也发布紧...
中国科学院自动化研究所蒲志强:... 来源:环球网 【环球网低空经济 记者 赵汗青 任卓成】7月5日,北京国家会议中心,2025国际无人机...