auto
是 C++11 引入的類型自動推導關鍵字,它允許編譯器根據表達式的類型來推導變量的確切類型。雖然使用 auto
可以讓代碼更簡潔,但理解它的類型推導規則非常關鍵,尤其是在涉及指針、引用、const、模板等場景時。
? 一、基本推導原則
auto x = expression;
編譯器根據 expression
的 值類型 推導出 x
的 精確類型(類似函數模板參數推導)。
🔸二、常見推導規則總結表
表達式類型 | 推導結果 | 說明 |
---|---|---|
值類型(int, double) | 相同類型 | 基礎類型正常推導 |
引用類型(int&) | 去掉引用 | auto 默認不會保留引用 |
const 值 | 去掉 const | auto 默認不會保留頂層 const |
指針類型 | 保留指針類型 | auto p = &x; 推導為 int* |
const 指針 | 保留指針本身的 const,但去掉指向對象的頂層 const |
🔹三、關鍵例子:值/引用/const
1. 默認去引用、去頂層 const
int a = 10; const int b = 20; auto x = a; // int auto y = b; // int (const 被去掉)
2. 顯式保留引用(用 auto&
)
int a = 10; auto& x = a; // int&,引用保留 const auto& y = a; // const int&,也保留 const
🔹四、數組與函數類型推導
1. 數組會退化為指針
int arr[3] = {1, 2, 3}; auto x = arr; // int*,數組退化成指針 auto& y = arr; // int(&)[3],引用才保留數組類型
2. 函數也會退化為函數指針
void func(int) {} auto x = func; // void(*)(int) auto& y = func; // void(&)(int)
🔹五、auto
vs decltype(auto)
關鍵字 | 推導方式 |
---|---|
auto | 類似模板參數推導(去引用、const) |
decltype(auto) | 完全等價于表達式的類型(保留引用、const) |
int a = 42; int& ra = a; auto x = ra; // int(去掉引用) decltype(auto) y = ra; // int&(保留引用)
🔹六、auto
與范圍 for 循環
1. 正確使用 auto&
防止拷貝:
std::vector<int> v = {1, 2, 3}; for (auto x : v) { x += 1; // 拷貝,每次循環操作副本 } for (auto& x : v) { x += 1; // 引用,直接修改原始元素 }
🔹七、配合 const
使用
-
auto
不保留頂層 const,需要顯式加上:
const auto x = expr; // x 是 const const auto& y = expr; // const 引用
? 八、小結:auto
推導的三個關鍵“默認行為”
特性 | 是否保留 | 說明 |
---|---|---|
引用 | ?(默認不保留) | auto 默認推導為值類型 |
頂層 const | ?(默認不保留) | 推導為非 const |
指針 / 函數 / 數組 | ?(但有退化) | 數組退化為指針,函數退化為函數指針 |