C++11开始改变了C++98中关键字auto的定义,使得C++可以在一些情况下不用写长长的变量类型,例如:
std::vector<SomeType> a; for(auto p = a.begin(); p != a.end(); p++){} 或 for(auto&p : a){} // c++11 for
这里auto省去了冗长的变量类型的书写,尤其是当“SomeType”是由多层模板得到的时候,变量名的长度简直就是噩梦,如果这个变量是一个库中的函数返回值则更加糟糕,有可能你完全不知道这是个什么类型。
auto还可以接复杂的lambda表达式,例如:
auto lambda = [](int x) { return x + 3; };
decltype是C++11引进的新关键字,和之前typeid看起来有点像但是好用的多
decltype可以获取一个变量或表达式的类型并直接使用,例如:
int a = 1; decltype(a) b = a + 1; double c = 2.3; decltype(a + c) d; // d的类型取决于a+c的类型
说到这里,如果想打印一个变量类型名,则使用typeid().name(),和decltype没有关系,例如:
int a = 1; std::cout << typeid(a).name() << std::endl;
auto不可以做为函数参数,但可以借助模板函数和decltype关键字实现省略不知道(或太长不想写)的参数类型。
如一个模板函数如下:
template <typename Itr> decltype(auto) func(std::function<void(Itr p, double& x> lambda, Itr begin = 0, Itr end = 0){return ...;}
则可以这样使用:
func<decltype(a.begin())>([](auto p, double& x){}, a.begin(), a.end());
func<>()的<>中本应该输入a.begin()的具体类型,但由于太长,想省略,直接使用auto是不被允许的,但是加上这个decltype就可以了。
函数的返回值类型则可以用decltype(auto)的方式表达(只有返回值可以这样用,函数参数是不可以的),返回类型取决于return的是什么。
值得注意的是,函数的第一个参数lambda表达式中的参数类型可以使用auto,这也是auto可以做为参数出现的唯一情况,并且只能出现在函数调用的时候,函数声明和定义的时候依然需要使用Itr类型。
C++17还支持auto做为模板类型(尚未测试)
template<auto n> // C++17 auto parameter declaration auto f() -> std::pair<decltype(n), decltype(n)> // auto can't deduce from brace-init-list { return {n, n}; }