前言
在《不想写表达式的类型?试试auto吧》中介绍了自动类型推导,它需要有初始值,今天再来介绍一个C 11中的特性,decltype。
作用
- 从表达式类型推断要定义的变量类型
- 声明返回类型依赖形参类型的函数模板
不过decltype并不会对表达式进行求值。
用法
decltype根据表达式的类型来获取类型。
代码语言:javascript复制int a = 1024;
decltype(a) b;//decltype(a),得到int,b为int类型
const char c = 'c';
decltype(c) d = 'd';//d是 const char
int &e = a;
int g = 11;
decltype(e) f = g ;//f是int &,必须初始化
不过下面这种情况需要注意:
代码语言:javascript复制int a = 10;
int *p = &a;
decltype(*p) c= a; //c是int &
虽然*p解引用后得到int,但是,c是引用类型,即如果表达式的内容是解引用,将会得到引用类型。
还有双重括号的情况:
代码语言:javascript复制int a = 10;
decltype((a)) b = a;//b是int &
如果加了双重括号,它最终也会得到引用类型。
常见应用场景
泛型编程中,如果返回类型与形参类型相关,那么可以使用下面的方式:
代码语言:javascript复制//来源:公众号【编程珠玑】 https://www.yanbinghu.com#include<iostream>
template <typename T>
auto add(T x, T y)->decltype(x)
{
return x y;
}
int main()
{
int a = 10;
int b = 12;
auto c = add(a,b);
std::cout<<c<<std::endl;
return 0;
}
add函数的返回类型与形参类型T有关,因此为了得到返回类型,我们使用auto关键字,但是需要decltype指明是通过表达式x得到的类型。
再比如你想给某个复杂类型取一个别名:
代码语言:javascript复制vector<int> vec
typedef decltype(vec.begin()) vecItType;
总结
decltype虽然对于不同场景下得到的类型不同,但是建议在一些不容易产生歧义的方面使用,不应牺牲代码的可读性。