C++ 中的关键字 auto(自 C++11 起)允许编译器根据初始化表达式自动推导变量的类型。这简化了长类型的处理(例如,在处理迭代器、Lambda 表达式、模板表达式时),并提高了代码的可读性。
使用示例:
auto i = 42; // int auto d = 3.14; // double auto s = std::string("hi"); auto it = v.begin(); // 迭代器
然而,auto 会严格按照它“所接收到”的内容推导类型。例如,如果按值返回,auto 将得到值;如果按引用返回,将得到引用。在处理引用、指针和 const 修饰符时应谨慎。
重要示例:
std::vector<int> v = {1,2,3}; for (auto x : v) x = 0; // 复制,v 不会改变 for (auto& x : v) x = 0; // 引用,元素将被置为 0
在表达式
const auto z = foo();中,如果方法foo()返回一个 int 的引用 (int&),变量 'z' 将是什么类型?
答复:
const auto z 的推导类型将是 int(值),即使返回的是引用。要推导引用,必须使用 auto& z。const 修饰符将在类型推导 之后 应用到自动类型上。
示例:
int x = 5; auto a = x; // a — int auto& b = x; // b — int& const auto c = x; // c — const int auto d = foo(); // d — int(如果 foo 返回 int) auto& e = foo(); // e — int&
故事
在一个大型网站中,使用基于范围的 for 循环时使用 auto 而不是 auto& 来处理智能指针集合。这导致对象复制,这使得程序在处理数百万条记录时变慢了 16 倍。
故事
在图形库中,auto 应用于返回的迭代器,期望这是一个引用,结果得到了一个临时对象。迭代器过早失效,循环后程序崩溃了。
故事
在金融系统中,由于使用 auto 从 map 中获取值,忽略了键的常量性,导致试图通过非常量引用修改数据,从而导致编译错误和运行时崩溃。