auto 是 C++ 里非常重要、刷题和工程都会大量用到的关键字
一、auto 是什么?
auto让编译器根据初始化表达式,自动推导变量的类型。
你不用手写类型,编译器帮你"算出来"。
二、最基础的用法
1️⃣ 变量定义
cpp
auto x = 10; // int
auto y = 3.14; // double
auto s = string("a"); // string
等价于你手写:
cpp
int x = 10;
double y = 3.14;
string s = "a";
⚠️ 必须初始化,否则无法推导:
cpp
auto a; // ❌ 错
三、auto + 引用 / const(非常重要)
2️⃣ auto& ------ 引用,避免拷贝
cpp
vector<int> v{1,2,3};
for (auto& x : v) {
x++; // 修改原数组
}
x是int&- 不拷贝,能修改
3️⃣ const auto& ------ 只读引用(最常用)
cpp
for (const auto& x : v) {
cout << x;
}
- 不拷贝
- 不能修改
- 遍历容器的首选写法
4️⃣ auto(无 &)------ 会拷贝
cpp
for (auto x : v) {
x++; // 只改拷贝,不改 v
}
四、auto 在结构化绑定中的用法(C++17)
cpp
pair<int,int> p = {1,2};
auto [a, b] = p;
等价于:
cpp
int a = p.first;
int b = p.second;
⚠️ 结构化绑定只能用 auto,不能写具体类型。
引用版结构化绑定(常用)
cpp
auto& [a, b] = p; // 可修改 p
const auto& [a, b] = p; // 只读
五、auto 在函数返回值中的用法
1️⃣ 接收返回值
cpp
auto res = dfs(root); // res 类型由 dfs 返回值决定
2️⃣ 返回类型推导(C++14)
cpp
auto add(int a, int b) {
return a + b; // 返回 int
}
六、auto 在 STL / 刷题中的典型场景
1️⃣ 遍历容器(99% 推荐)
cpp
for (const auto& it : container) { ... }
2️⃣ 接收复杂类型
cpp
unordered_map<string, vector<pair<int,double>>> mp;
for (const auto& [key, vec] : mp) { ... }
3️⃣ DFS / 树 DP 返回 pair
cpp
auto [take, skip] = dfs(node);
七、auto 的推导规则(知道这 3 条就够)
1️⃣ auto 会丢掉顶层 const
cpp
const int x = 10;
auto y = x; // y 是 int
2️⃣ auto& 会保留引用和 const
cpp
const int x = 10;
auto& y = x; // y 是 const int&
3️⃣ 初始化表达式决定一切
cpp
auto a = {1,2,3}; // initializer_list<int>
八、常见坑(一定要避开)
❌ 误以为 auto 不会拷贝
cpp
for (auto x : bigVector) { ... } // 每次拷贝
改为:
cpp
for (const auto& x : bigVector) { ... }
❌ 结构化绑定写成具体类型
cpp
pair<int,int> [a,b] = p; // ❌
只能:
cpp
auto [a,b] = p; // ✅
❌ 忽略 auto 推导导致类型变化
cpp
auto x = 0; // int
x = 3.14; // 3,被截断
九、什么时候"应该"用 auto?
✅ 强烈推荐用 auto 的情况
- 类型很长(STL 容器)
- 遍历容器
- 接收函数返回值
- 结构化绑定
⚠️ 不建议用 auto 的情况
- 类型对可读性很关键(如
int/double混用) - API 对外接口(头文件)
十、刷题级使用口诀
遍历容器用
const auto&要改元素用
auto&拿返回值用
auto解构
pair/tuple用auto [a,b]
十一、一句话面试总结
auto是编译期类型推导工具用来减少冗余、避免拷贝、提升可读性
但要配合
&/const使用,避免隐式性能问题