2_9_2 万能引用、引用折叠、完美转发、forward

9_2_universal_reference.cpp

#include "hjcommon.hpp"

static void bcd(int &&num) {}
template<typename T>
static void cde(const T &&t) {} // 不是万能引用,const 会剥夺 T&& 的万能引用性质
template<typename T>
static void abc(T &&t) {} // 万能引用
template<typename T>
static void def(vector<T>&& vec) {} // 不是万能引用

template<typename T> class A
{
public:
	void func1(T&& t) {} // 不是万能引用,是右值引用
	template<typename W>
	void func2(W&& w) {} // 万能引用
};

int main_2_9_2(int argc, char *argv[])
{
	int num = 0;
//	bcd(num); // 不可以,不可以将左值赋给右值引用
	bcd(0); // 可以
//	cde<int>(num); // 不可以
//	cde(num); // 不可以
	cde(0); // 可以
//	abc<int>(num); // 不可以
	abc(num); // 可以,但若是函数模板形参改为 const T && ,就又不行了
	abc(0); // 可以

	// universal reference 万能引用/未定义引用
	// 万能引用语境:必须是函数模板、必须是发生了模板类型推断并且函数模板形参样子必须是 T&&, (const T&& 不行)、auto也存在万能引用的概念
	// 此时 T&& 就称为万能引用,若传参左值,那么此时万能引用会变成左值引用。若传参右值,那么此时万能引用会变成右值
	auto &&a1 = 0; // 可以,也是万能引用
	auto &&a2 = num; // 可以,也是万能引用

	A<int> a;
//	a.func1(num); // 不可以
	a.func2(num); // 可以

	return 0;
}

9_4_引用折叠_完美转发_forward.cpp

#include "hjcommon.hpp"

template<typename F, typename T, typename Q>
static void tempPerfectFunc(F f, T&& t, Q&& q) // 使用万能引用,既能保持const属性,又能保持左值右值属性
{
	// 通过函数模板去调用另一个普通函数,这种形式就叫转发。
	f(std::forward<T>(t), std::forward<Q>(q)); // 在万能引用的基础上转发时使用 std::forward<>() 就能实现完美转发。
}
static int aFunc(int &a, int &&b)
{
	++a;
	return a+b;
}

int main_2_9_4(int argc, char *argv[])
{
	// 引用折叠(引用坍塌),c++11 : 当编译器发生类型推断出现多个 & 时,就会发生引用折叠,左-左、左-右、右-左 这三种只要左值的情况,最终变量会折叠为左值, 右-右 折叠为右值。
	// 引用的引用: int a=0; int &b=a; int & &c=b; // 语法明写会报错,但是编译器在进行类型推断时可能会出现这种引用的引用,这时会用引用折叠来处理。

	// 转发、完美转发、std::forward(还原变量的左值或右值属性)
	int a = 10;
	tempPerfectFunc(aFunc, a, 50); // 完美转发
	cout << "a=" << a << endl; // a=11

	// std::forward<>() 另外用法
	int b = 0;
	int &&c = std::forward<int>(b); // 利用forward将左值转右值

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值