先来说一下 decltype 的这个概念, decltype 是一个推到类型,在C++ 中的推到类型常常使用 auto ,但是 auto 的使用存在一些限制
举个例子
arduino
template<class T>
auto getT(T t)-> decltype (t){
return t;
}
在上面这段代码中,使用了模板类型,你传入的类型是什么,我就给你返回什么类型, 如果不使用 decltype 约束返回类型是 t 的类型,那么这段代码就无解了,
decltype 获取的常常是变量的左值,也就是变量的类型 ,配合 typeid 可以获取 左值类型的id
arduino
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
template<class T>
auto get_decltype(T t) -> decltype(t) {
return t;
}
int main(){
decltype(get_decltype(10)) tsm_int =10;
// typeid 返回类型是一个 typeinfo ,他在 <typeinfo> 这个包下
cout<< "tsm 实际的类型是" << (typeid(tsm_int).name()) <<endl;
return 0;
}
结果:
vbnet
D:\CWorkSpace\tsmTest\cmake-build-debug\tsmTest.exe
tsm 实际的类型是i
Process finished with exit code 0
可以看到 int 的类型是i, 从网上查了一下,由于编译器的差异导致的,并不是错误
我们来增加点难度
arduino
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
template<class T>
auto get_decltype(T t) -> decltype(t) {
return t;
}
int compare(int a,int b){
if(a>b)
return 1;
else return 0;
}
int main(){
const int i=45;
// 有点类似 java 中的 二目三项式 ,只不过他指定的是左值, java 的 二目三项式指定的是右值
conditional< (i>100),int,conditional< (i>50) ,double ,float >::type >::type a;
cout<< "tsm 实际的类型是" << (typeid(a).name()) <<endl;
return 0;
}
结果:
vbnet
D:\CWorkSpace\tsmTest\cmake-build-debug\tsmTest.exe
tsm 实际的类型是f
Process finished with exit code 0
这里面使用了 conditional 来指定 i 在不同范围 , a 的类型是不同的,
那么 conditional 的用法又是什么样子的呢
c
//// conditional 简单用法
conditional<false,int,double>::type b;
cout<< "tsm 实际的类型是" << (typeid(b).name()) <<endl;
源码
arduino
template<typename _Iftrue, typename _Iffalse>
struct conditional<false, _Iftrue, _Iffalse>
{ typedef _Iffalse type; };
从源码看起来好像也比较简单, 如果是false 使用 _Iffalse 的typename ,如果是true使用 _Iftrue 的typename
conditional typeid decltype 都是在 template 中经常被用到的地方