auto 和 decltype
C++11引入了auto和decltype关键字,使用它们可以在编译期就推导出变量或者表达式的类型。
auto
auto 让编译器通过初始值来推算变量的类型。显然,auto 定义的变量必须偶初始值。auto在一行定义多个变量时,各个变量的推导不能产生二义性,否则编译失败。
auto item = val + val2;
auto F() -> std::vector<int> { // c++11
return ...;
}
auto F() { // c++14
return ...;
}
auto 不能用作函数参数
在类中 auto 不能用作非静态成员变量
通常会在lambda表达式中使用
auto func = [&] {
cout << "xxx";
}; // 对于func你难道不使用auto吗,反正我是不关心lambda表达式究竟是什么类型。
在不声明为引用或指针时,auto会忽略等号右边的引用类型和cv限定
在声明为引用或者指针时,auto会保留等号右边的引用和cv属性
int i = 0;
auto *a = &i; // a是int*
auto &b = i; // b是int&
auto c = b; // c是int,忽略了引用
const auto d = i; // d是const int
auto e = d; // e是int 忽略了 const
const auto& f = e; // f是const int&
auto &g = f; // g是const int&
decltype
auto 用于推导变量类型,而 decltype 则用于推导表达式类型,这里只用于编译器分析表达式的类型,表达式实际不会进行运算。
int func() { return 0; }
decltype(func()) i; // i为int类型
decltype不会像auto一样忽略引用和cv属性,decltype会保留表达式的引用和cv属性
cont int &i = 1;
int a = 2;
decltype(i) b = 2;// b是const int&,在其他地方引用从来就是所指对象的同义词,只有在decltype处例外
exp是表达式,decltype(exp)和exp类型相同
exp是函数调用,decltype(exp)和函数返回值类型相同
其它情况,若exp是左值,decltype(exp)是exp类型的左值引用
int a = 0, b = 0;
int *p = &a;
decltype(a + b) c = 0; // c是int,因为(a+b)返回一个右值
decltype(a += b) d = c;// d是int&,因为(a+=b)返回一个左值
decltype(*p) e; // *p 解引用是一个左值, c 是 int& 必须初始化
对编译器来讲 deltype((i))
对把 (i)
当成一个表达式,所以就会被视为左值,结果自然就是左值引用。不加括号的话得到的就是该变量的类型。
declval
declval 是一个函数而 deltype 是一个运算符,declval 返回一个对应类型的值。
auto i = std::declval<int>();