(C++模板编程):萃取技术及fixed traits -- 引用类型的移除和增加

萃取技术及fixed traits -- 引用类型的移除和增加

引用类型的移除

【std::remove_reference类模板】

template <class T1,class T2>
void print_is_same()
{
	cout << "T1类型为:" << typeid(T1).name() << endl;
	cout << "T2类型为:" << typeid(T2).name() << endl;
	cout << "T1类型和T2类型是否相等:" << std::is_same<T1, T2>() << endl;
	//cout << "T1类型和T2类型是否相等:" << std::is_same<T1, T2>::value << endl;
	    //值为1则表示2个类型相等,值为0表示2个类型不等,is_same是标准库中用于判断两个类型是否相同的类模板,
	    // std::is_same<T1,T2>()写法写成 std::is_same<T1,T2>::value  效果也是一样的
}
  • 调用
std::remove_reference<int>::type a;
std::remove_reference<int&>::type b;
std::remove_reference<int&&>::type c;

print_is_same<decltype(a), decltype(b)>();
print_is_same<decltype(a), decltype(c)>();
  • 输出

【std::remove_reference_t】

//c++14中定义别名
template<class T>
using remove_reference_t = typename remove_reference<T>::type;
  • 调用
std::remove_reference_t<int> a;
std::remove_reference_t<int &> b;
std::remove_reference_t<int&&> c;

print_is_same<decltype(a), decltype(b)>();
print_is_same<decltype(a), decltype(c)>();
  • 输出

  

【实现remove_reference功能】

//泛化版本
template <typename T>
struct RemoveReference
{
	using type = T;
};

//特化版本
template <typename T>
struct RemoveReference<T&>
{
	using type = T;
};
template <typename T>
struct RemoveReference<T&&>
{
	using type = T;
};
//别名模板
template <typename T>
using RemoveReference_t = typename RemoveReference<T>::type;
  • 调用
int&& a2 = 12;
//RemoveReference_t<decltype(a2)> b2 = "dd";  //error C2440: “初始化”: 无法从“const char [3]”转换为“int”
RemoveReference_t<decltype(a2)> b2 = 125;
int i = 64;
int& c2 = i;
RemoveReference_t<decltype(c2)> d2 = 500;
using boost::typeindex::type_id_with_cvr;
cout << "b2= " << type_id_with_cvr<decltype(b2)>().pretty_name() << endl;
cout << "d2= " << type_id_with_cvr<decltype(d2)>().pretty_name() << endl;
  • 输出

引用类型的增加

  • 根据给定的类型来创建一个左值或者右值引用
    • std::add_lvalue_reference类模板:给进来 一个类型,返回该类型对应的左值引用类型
    • std::add_rvalue_reference类模板:给进来 一个类型,返回该类型对应的右值引用类型
  • std::is_lvalue_referencestd::is_rvalue_reference类模板:判断某个类型是否是左值引用类型或者右值引用类型。

【引例】

int a = 15;
std::add_lvalue_reference<decltype(a)>::type b = a; //b的类型为int &
std::add_rvalue_reference<decltype(a)>::type c = 16; //c的类型为int &&

using btype = std::add_lvalue_reference_t<int>; //_t是个别名模板
cout << std::is_same<int&, btype>() << endl;  //1

using ctype = std::add_rvalue_reference_t<int>;
cout << std::is_lvalue_reference<btype>::value << endl; //1
cout << std::is_rvalue_reference<ctype>::value << endl; //1

std::add_rvalue_reference_t<int&> cc1 = a; //cc1类型为int &,这里涉及到引用折叠, &  和&& 折叠后得到 &
std::add_rvalue_reference_t<int&&> cc2 = 16; //cc2的类型为int &&,这里涉及到引用折叠,&&和&&折叠得到&&

【实现引用类型的增加功能】

template<typename T>
struct AddLValueReference
{
	using type = T&; 
    //如果传入int && & ,引用折叠:有左值 引用,结果必然为左值 引用,所以type = int &
};
template<typename T>
using AddLValueReference_t = typename AddLValueReference<T>::type; 
//实际上可以直接简化为using AddLValueReference_t = T&;,这样就不用定义AddLValueReference了。

//--------------------------
template<typename T>
struct AddRValueReference
{
	using type = T&&;
};
template<typename T>
using AddRValueReference_t = typename AddRValueReference<T>::type; 
//实际上可以直接简化为using AddRValueReference_t = T&&;,这样就不用定义AddRValueReference了。
  • 调用
int anew = 15;
AddLValueReference_t<decltype(anew)> bnew = anew; 
//decltype(anew)的类型是int,bnew的类型为int &

int&& anew2 = 16;
AddLValueReference_t<decltype(anew2)> bnew2 = anew;
//decltype(anew2)的类型是int&&,bnew的类型为int &


int argnew = 15;
AddRValueReference_t<decltype(argnew)> brgnew = 18; //brgnew的类型为int &&

int&& argnew2 = 15;
AddRValueReference_t<decltype(argnew2)> brgnew2 = 18;//brgnew2的类型为int &&

int tmpvalue = 16;
int& argnew3 = tmpvalue;
AddRValueReference_t<decltype(argnew3)> brgnew3 = tmpvalue; 
//brgnew3的类型为int &,因为根据引用折叠规则,左值引用和右值引用遇到一起,结果是左值引用。
  • 注意引用折叠。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值