auto与decltype
在C++中,有时候我们不知道某个变量x应该定为何种数据类型,但是我们知道他和另一个变量/函数有关系,这种情况下,可以通过auto或者decltype来初始化这个变量,让编译器自行判断其类型。
auto
首先看下面的代码,这里通过auto初始化x=0和*p=x,编译器很聪明地读懂了我的意思,把x定为int类型,p定义为int的指针。
#include <iostream> #include<typeinfo> using namespace std; int main() { auto x=0,*p=&x; cout<<typeid(x).name()<<endl; cout<<typeid(p).name()<<endl; return 0; }
i Pi
有时候,编译器可能并不能读懂你的意思,例如引用,使用引用其实是使用引用的对象,这时候如果使用auto,那么编译器会选择引用对象的类型作为auto的类型,下面例子中,r是对i的引用,但是在auto的时候,a是一个int型,而非引用类型,这是值得注意的。
第二点需要注意的是,auto会忽略掉顶层const,保留底层const,顶层与底层const可以见另一篇文章关于const的用法 - para_dise - 博客园 (cnblogs.com)。在下面的例子中,ci是const int型,但是在初始化b的时候,auto会忽略这个顶层const,会初始化为int类型,如果需要保留顶层const特性,需要如f一般重新声明。
int i=0,&r=i; auto a=r; //a是一个整数 const int ci=i,&cr=ci; auto b=ci; //b是一个整数 auto c=cr; //c是一个整数 auto d=&i; //d是一个整型指针 auto e=&ci; //e是一个指向整数常量的指针 const auto f=ci;//ci的推演类型是int,f是const int auto &g=ci; //g是一个整型常量引用,绑定到ci
decltype
有时候,我们只想要他的类型,但是不想用他的值初始化,这时候可以用decltype实现。
decltype可以继承const和引用,如下:
decltype(f()) sum=x; //sum的类型是函数f的返回类型 const int ci=0,&cj=ci; decltype(ci) x=0; //x是const int decltype(cj) y=x; //y是const int& 并绑定到x上(引用必须初始化)
想获得引用对象的类型,那么可以通过加0的办法,使其成为int类型,如果想要变成一个变量的引用,可以通过加括号的办法。
int i=42,*p=&i,&r=i; decltype(r+0) b; //加法的结果是int,因此b是一个未初始化的int decltype(*p) c=i; //*p是解引用,因此得到的c是一个引用,这里将其绑定到a decltype((i)) d=i; //变量名+括号,结果也是引用,绑定到i
综上,auto与decltype各有各自的应用场景,最好结合实际使用。