编程后端 C++ 开发者

描述 C++ 中的关键字 'auto'。它是如何在类型推导中工作的?在什么情况下可能导致错误?使用 auto 什么时候潜在危险?

用 Hintsage AI 助手通过面试

答复

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& zconst 修饰符将在类型推导 之后 应用到自动类型上。

示例:

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 中获取值,忽略了键的常量性,导致试图通过非常量引用修改数据,从而导致编译错误和运行时崩溃。