06 - auto关键字

auto关键字

auto告诉编译器,在编译期自动推断变量的类型,简单来说就是简化了一些写法。使用它推断类型确实简单方便,但有个基本要求:在使用auto时必须清楚的知道编译器会给auto推断出什么类型

在Windows平台,可以使用VS2022的类型推断,只需用鼠标指一指就行。也能用Boost库来进行类型推断。使用Boost库的示例代码如下:

#include <boost/type_index.hpp>
#include <iostream>

using boost::typeindex::type_id_with_cvr;

int main()
{
  int p{ 10 };
  std::cout << type_id_with_cvr<decltype(p)>().pretty_name() << std::endl;

  return 0;
}

输出为int

※ auto的推断规则

  • 使用auto推断类型时去掉了引用和const限定符。也可以换种角度来理解,auto只能推断出类型,而引用不是类型,因此要使用引用得自己加上引用符号:
int i{ 10 };

auto i1{ i };
auto& i2{ i };

i1的类型为int,i2的类型为int &

  • auto关键字在推断类型时,会直接将引用替换为引用指向的对象。这其实是引用的特性,引用不是对象,是对象的别名,任何使用引用的地方都可以直接替换为引用指向的对象:
int i{ 10 };
const int& refI{ i };

auto i2{ refI };
auto& i3{ refI };

i2的类型为int,i3的类型为int const &.

  • auto关键字在推断类型时,如果没有引用符号,会忽略值类型的const修饰,而保留指向对象的const
int i{ 10 };
const int* const pi{ &i };

auto i2{ pi };

i2的类型为const int*。pi的定义可以写成int const* const,由于忽略值类型的const修饰,会忽略第二个const(修饰指针它本身的),留下int const*,即const int*

  • auto关键字在推断类型时,如果有了引用符号,那么值类型和指向对象的const都会保留。
int i{ 10 };
const int* const pi{ &i };

auto& i2{ pi };

i2的类型为int const* const &.

当然,也能直接在auto前边加上const,这样永远都有const的含义。

auto的注意点

  1. auto不会影响编译速度,甚至还会加快编译速度。因为编译器在处理 XX a = b 时,当XX 是传统类型时,编译期需要检查 b 的类型是否可以转化为 XX。当 XX 为 auto 时,编译期可以按照 b 的类型直接给定变量 a 的类型,所以效率相差不大,甚至反而还有提升。

  2. auto不要滥用,对于一些自己不明确的地方不要乱用auto,否则很可能出现事与愿违的结果,使用类型应该安全为先。

std::string str {"wuhu"};
auto result { as_const(str) };

as_const()函数返回其引用参数的const引用版本,即const std::string &, 而根据上边规则,result的类型只能是std::string,正确做法应使用auto&

  1. auto 主要用在与模板相关的代码中,一些简单的变量使用模板常常导致可读性 下降,经验不足还会导致安全性问题。

参考资料

  • 飘零的落花 - 现代C++详解
  • C++20高级编程