编译器支持最低版本要求:
- GCC: 4.4(v1.0)
- MSVC: 16.0(v0.9)
- Clang: Yes
提案: N1984(v1.0)
自动类型推导是降低编码负担的一种手段,在其他编程语言比如Go中也有类似的功能。C++11修改了关键字auto
原有的作用,使其为自动类型推导所用。在C++11之前,template就已经具有类型推导能力,而C++11中增加的auto
通常情况下就是使用template的类型推导方式:
int main(int argc, char *argv[])
{
auto x = 17; // x = int
auto& y = x; // y = int&
const auto& i = x; // i = const int&
auto z = y; // z = int
const auto f = y; // f = const int
auto& m = i; // m = const int&
auto&& t = i; // t = int&
auto&& t1 = 10; // t1 = int&&
return 0;
}
int main(int argc, char *argv[])
{
int A[3] = {1, 2, 3};
auto a = A; // a = int *
auto& a1 = A; // a1 = int (&)[3]
return 0;
}
还有了新式的函数声明形式:
auto get_fun(int arg) -> double (*)(double) // same as: double (*get_fun(int))(double)
{
switch (arg)
{
case 1: return std::fabs;
case 2: return std::sin;
default: return std::cos;
}
}
auto
代替了声明变量时的强制类型信息如int
,int&
,const int&
,int&&
等等,但是在使用auto
时:
- 必须初始化变量,当然好的编码实践即使不用
auto
也会要求声明变量时立即初始化 - 函数返回值不能是
auto
(仅C++11而言,C++14中已经修改) - 函数的形参类型不能是
auto
,即使指定了默认参数也不行(仅C++11而言,C++14中lambda表达式部分已经修改) auto
不能声明为模板的参数(仅C++11而言?)- 非静态成员变量不能是
auto
的,即使指定了初始值也不行 - 不能声明
auto
数组
另外,由于C++11新增了初始化列表功能,使用auto
自动推导出来的类型可能会有出乎意料的情况:
int main(int argc, char *argv[])
{
int a0 = (1); // a0 = int
auto a1 = (1); // a1 = int
int a2 = {1}; // a0 = int
auto a3 = {1}; // a3 = std::initializer_list<int>
return 0;
}
a1
如愿得到int
类型,而a3
却跟a2
是不同的类型,因为初始化列表拥有特有的类型std::initializer_list<int>
。
一般而言,在以下场合使用auto
比较合适:
-
类型名比较长,比如
std::vector<std::string>::iterator
,std::shared_ptr<std::vector>
等等诸如此类的要声明变量可以使用auto
-
类型名比较难书写,比如临时定义一个lambda表达式,又要把它保存到一个变量中以便之后调用,就可以用
auto
:auto f = [&](int n)->int { return n+1; }; auto i = f(10);
-
Scott Meyers在《Effective Modern C++》中提议优先使用
auto
,这也许是一种趋势。