auto 与 decltype关键字
auto两个关键字都用来推断类型,c++作为一种强类型语言有这种关键字是很必要的,尤其是在模板编写的时候,根本无法知道一个变量或者函数的类型,只能使用这种方式推断。
比如一个接受迭代器的模板
template<typename It> ??? func(It it) { return *it; }
由于我们不知道迭代器的类型,所以也就不知道函数到底该返回什么类型。
一种解决办法是再加一个类型参数:
template<typename T, typename It> T func(It it) { return *it; }
但是这样一来,由于编译器只能从参数类型推断模板参数的类型,而不能从返回值类型推断模板参数类型,用户想使用这个模板,就必须显示的指定返回值类型。
fun<type>(x) //只需要显示指定第一个,即返回值类型,第二个是函数参数,可以自动推断
但是如果利用后置返回值类型和auto以及decltype关键字就可以这样:
template <typename It> auto func(It it) -> decltype(*it) { //尾置返回值声明解决了在编译器遇到it之前,无法使用decltype(*it)的问题 return *it; }
瞬间可读性上升了几个档次,用户在使用模板的时候也不必要显式的提供类型参数了
两个关键字的推断方式有些许差别:
auto:
//auto v会忽略掉顶层const,但是auto &v不会忽略掉顶层const,同时可以显示加上顶层const int i = 0; const int ci = i, &cr = ci; auto b = ci; //b的类型为int,非指针以及引用只有一个顶层const,顶层const被忽略 auto c = cr; //c的类型为int, 对于引用,得到的被引用的变量的类型,然后去掉顶层const auto d = &i; //d的类型为int * auto e = &ci; //e的类型为const int*,只会忽略掉顶层const,保留底层const const auto f = ci; //显示加上顶层const,由ci推出int,加上const auto &g = ci; // g为const int类型,使用引用时,ci的const变成了底层const auto &h = 42; //报错,只能引用左值
decltype:
//decltype会保留所有的引用、const const int ci = 0, &cj = ci; decltype(ci) x = 0; //x的类型为const int decltype(cj) y = x; //y的类型为const int & //对于表达式,则推测表达式的结果的类型 int i = 0; int *p = &i; decltype(*p) x; //出错,解引用得到的不是int,而是int& decltype((i)) y; // 出错,(i)是表达式,并且返回的是i引用,是左值,故推测到得类型为int& decltype(i) z; //正确,z是一个默认初始化的int类型
浙公网安备 33010602011771号