decltype(expression)
作用
它可以声明定义一个跟表达式内一模一样的值,包括const。其参数可以是表达式,也可以是普通的变量。
来源
在使用函数模板的时候,有一种问题是无法解决的:
template<class T1, class T2>
void ft(T1 x, T2 y){
...
?TYPE? xytype = T1 + T2;
...
}
这里根本无法去判断TYPE应该是什么类型才合适。基于此,才引出了个关键字。
详细说明
- 如果expression是一个没有用括号括起的标识符,则var的类型与该标识符的类型相同,包括const等限定符。
- 如果expression是一个函数,则var的类型与函数的返回类型相同。但并不会调用函数,只是获取其返回类型。
- 如果expression是一个左值,则var为指向其类型的引用。要进入第三步,expression不能是未用括号括起的标识符。一种显而易见的情况是,expression是用括号括起的标识符:
double xx = 4.4;
decltype((xx)) r2 = xx; //r2 is double &;
decltype(xx) r2 = xx; //w is double ;
- 如果前面的条件都不满足,则var的类型与expression的类型相同:
int j = 3;
int &k = j;
int &n = j;
decltype(j+6) i1;//int
decltype(100L) i2;//long
decltype(k+n) i3;//int
请注意,虽然k和n都是引用,但表达式k+n不是引用;它是两个int的和,因此类型为int。
多次声明
如果需要多次声明,可结合使用typedef和decltype:
template<class T1, class T2>
void ft(T1 x, T2 y){
typedef decltype(x+y) xytype;
xytype xpy = x+y;
xytype arr[10];
}
C++后置返回类型
说了那么多,其实有一个问题是decltype无法解决的。
template<class T1, class T2>
?type? gt(T1 x, T2 y){
return x+y;
}
同样,无法预先知道将x和y相加得到的类型。好像可以将返回类型设置为decltype ( x + y),但不幸的是,此时还未声明参数x和y,它们不在作用域内(编译器看不到它们,也无法使用它们)。必须在声明参数后使用decltype。为此,C++新增了一种声明和定义函数的语法。下面使用内置类型来说明这种语法的工作原理。对于下面的原型:
double h(int x , float y);//使用新增的语法可以编写成下面这样:
auto h(int x,float y)->double;
这将返回类型移到了参数声明后面。->double被称为后置返回类型。其中auto是一个占位符,表示后置返回类型提供的类型,这是C++11给auto新增的一种角色。
所以可以通过这种方法去解决:
template<class T1, class T2>
auto gt(T1 x, T2 y)->decltype(x+y){
...
return x+y;
}