c++引用

c++引用包含左值引用和右值引用,因为引用都是变量,因此右值引用是左值。
左值指变量,右值指临时对象,字面值(16,“string”,13+2)。

当函数参数为T&&时(其中T时模板类型),是万能引用,传入参数是左值,T&&就变成左值引用,否则T&&变成右值引用。


template<typename T> void f(T&& t);
int i=1;//如果i传入,在f内还能改变i的值,故为左值引用。

去引用

std::remove_reference<T>可以去除T的引用

T: int&& -->int;
T: int& --> int;

引用折叠

当模板类型是引用类型,而且函数参数是模板参数的引用的时候会发生引用折叠。
void func(T&&) ---> 当T==int&.

A&& & 折叠成 A&
A& & 折叠成 A&
A& && 折叠成 A&
A&& && 折叠成 A&&

也就是说引用类型和函数参数类型只要有一方为左值引用,就折叠成左值引用;如果双方都是右值引用,才折叠成右值引用。

move

move的作用是将 左值或者右值 强制转换成 右值引用类型。从而可以把左值或右值参数传入相应的函数。

template<class _T>
typename remove_reference<_T>::type&& move(T&& _Arg)
{	
	return static_cast<typename remove_reference<_T>::type<T>&&>(_Arg);
}

如何工作:
参数T&&保证左值(普通变量,左值引用,右值引用),右值(临时对象)都会进这个函数。

return:
普通变量 --> 临时对象(函数返回值)
临时对象 --> 临时对象(函数返回值)
左值引用 --> 右值引用
右值引用 --> 右值引用

forward

forward是完美转发,保持变量原有的左右值属性。右值参数–>赋值右值引用 --> 右值引用是变量(左值)–> 参数从右值变左值,调相应左值函数。
通过forward。右值参数–>赋值右值引用 --> 右值引用是变量(左值)–>forward将右值引用转成右值–> 参数为右值,调相应左值函数。

void f(int&& i)
{
	cout << "r ref" << endl;
}

void f(int& i)
{
	cout << "l ref" << endl;
}
void warp(int&& i)
{
	f(i);
}
void warp1(int&& i)
{
	f(forward<int>(i));
}
warp(13) --> l ref
warp1(13) --> r ref

源码

template<class _Ty>//func1
_NODISCARD constexpr _Ty&& forward(remove_reference_t<_Ty>& _Arg) noexcept
{	// forward an lvalue as either an lvalue or an rvalue
	return (static_cast<_Ty&&>(_Arg));
}

template<class _Ty>//func2
_NODISCARD constexpr _Ty&& forward(remove_reference_t<_Ty>&& _Arg) noexcept
{	// forward an rvalue as an rvalue
	static_assert(!is_lvalue_reference_v<_Ty>, "bad forward call");
	return (static_cast<_Ty&&>(_Arg));
}

如何工作:
参数remove_reference_t<_Ty>&保证左值(普通变量,左值引用,右值引用)进函数1 。remove_reference_t<_Ty>&& 保证右值(临时对象)都会进函数2。

普通变量 -->经过 func1参数,变为左值引用–> 左值引用
左值引用 -->经过 func1参数,变为左值引用–> 左值引用
临时对象 -->经过 func2参数,变为右值引用–> 右值引用
右值引用 --> 经过 func2参数,变为右值引用–> 右值引用

理解就好,写代码时也不用考虑这么细吗?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值