一、进行自动类型推导
- auto 的自动类型推断发生在编译期,所以使用 auto 并不会造成程序运行时效率的降低。
- 而是否会造成编译期的时间消耗,我认为是不会的,在未使用 auto 时,编译器也需要得知右操作数的类型,再与左操作数的类型进行比较,检查是否可以发生相应的转化,是否需要进行隐式类型转换。
- auto 属于类类型推导
- decltype 是包含声明修饰符的声明类型推导
int main()
{
int a = 10;
auto val = a;
cout << typeid(val).name() << endl; // i
return 0;
}
二、在定义函数模板时,用于声明依赖模板参数的变量类型
不到编译的时候,x * y
的真正类型很难确定
template <class _Tx,class _Ty>
void Multiply(_Tx x, _Ty y)
{
auto v = x * y;
std::cout << v;
}
int main()
{
int a = 10;
double b = 1.53;
Multiply(a, b); // 15.3
return 0;
}
三、函数模板返回值依赖于模板参数
auto 在这里的作用也称为返回值占位,真正的返回值是后面的 decltype(x * y)。为何要将返回值后置呢?如果没有后置,则函数声明时为:decltype(x * y) multiply(_Tx x, _Ty y)
,而此时 x, y
还没声明呢,编译无法通过。
template <class _Tx,class _Ty>
auto Multiply(_Tx x, _Ty y) -> decltype(x * y)
{
return x * y;
}
int main()
{
int a = 10;
double b = 1.53;
cout << Multiply(a, b) << endl;
return 0;
}
四、与匿名函数结合使用
int main()
{
auto f = [](int a, int b) -> int
{
return a * b;
};
decltype(f) g = f; // lambda 的类型是独有且无名的
// 也不用定义函数指针了
cout << typeid(f).name() << endl;
auto i = f(2, 2);
decltype(g(3, 3)) j = g(3, 3);
cout << "i = " << i << ", "
<< "j = " << j << '\n';
return 0;
}
输出:
Z4mainEUliiE_
i = 4, j = 9
五、auto 注意事项
-
auto 变量必须在声明时初始化,这类似于 const 关键字。
-
定义在一个 auto 序列的变量必须始终推导成同一类型。
auto a4 = 10, a5 = 20, a6 = 30; //正确 auto b4 = 10, b5 = 20.0, b6 = 'a'; //错误
-
如果初始化表达式是引用,则去除引用语义。
int main() { int a = 10; int &b = a; auto c = b; // c的类型为int而非int&(去除引用) auto &d = b; // 此时c的类型才为int& c = 100; //a = 10; cout << "c = " << c << " a = " << a << endl; d = 100; //a = 100; cout << "d = " << d << " a = " << a << endl; return 0; }
输出:
c = 100 a = 10 d = 100 a = 100
-
如果初始化表达式为 const 或 volatile(或者两者兼有),则除去 const/volatile 语义
-
如果 auto 关键字带上 & 号,则不去除 const 语义
int main() { const int a1 = 10; auto b1= a1; // b1的类型为int而非const int(去除const) // 与指针类似,只是为新变量开辟了新的空间 int* pB1 = (int*)&a1; b1 = 100; // 合法 *pB1 = 1000; // 合法 cout << "b1 = " << b1 << endl; cout << "a1 = " << a1 << endl; cout << "*pB1 = " << *pB1 << endl; const auto c1 = a1; // 此时c1的类型为const int // c1 = 100; // 非法 auto& b2 = a1; // 因为auto带上&,故不去除const,b2类型为const int // b2 = 100; // 非法 return 0; }
输出:
b1 = 100 a1 = 10 *pB1 = 1000
-
初始化表达式为数组时,auto 关键字推导类型为指针。
-
若表达式为数组且 auto 带上 &,则推导类型为数组类型。
int main() { int a3[3] = { 1, 2, 3 }; auto b3 = a3; cout << typeid(b3).name() << endl; auto& c3 = a3; // int (&)[3] cout << typeid(c3).name() << endl; return 0; }
输出:
Pi A3_i
-
函数形参或者模板参数不能被声明为 auto。
六、decltype 声明引用类型
struct A { double x; };
const A* a;
decltype(a->x) y; // y 的类型是 double(其声明类型)
decltype((a->x)) z = y; // z 的类型是 const double&(左值表达式)