C++ auto 類型推導(dǎo)規(guī)則與模板類型推導(dǎo)類似企垦,兩者只有一點不一樣似忧。
前面說過,模板的聲明和使用方式如下:
template<typename T>
void f(ParamType param);
f(expr);
auto的使用方式如下:
auto x = 27;
const auto cx = x;
const auto& rx = x;
在auto進(jìn)行類型推導(dǎo)的時候蚕冬,auto相當(dāng)于模板里的T纺座,變量類型修飾符相當(dāng)于ParamType速侈,等號右邊的部分相當(dāng)于expr显设。例如:
auto x = 27;
// 進(jìn)行x的類型推導(dǎo)僻澎,就如同下面的模板類型推導(dǎo)
template<typename T>
void func_for_x(T param);
func_for_x(27);
// 27是int型废封,根據(jù)上篇文章的推導(dǎo)規(guī)則州泊,param是int型,因此x也是int型漂洋。
const auto& rx = x;
// 進(jìn)行rx的類型推導(dǎo)遥皂,就如同下面的模板類型推導(dǎo)
template<typename T>
void func_for_rx(const T& param);
func_for_rx(x);
// x是int型,模板推導(dǎo)出的param類型是const int&,因此rx也是const int&刽漂。
auto類型推導(dǎo)規(guī)則根據(jù)類型修飾符也分三種情形演训,與模板類型推導(dǎo)完全一致,對數(shù)組參數(shù)和函數(shù)參數(shù)的處理也完全一致贝咙,不再贅述样悟。
開頭說過,有一種情形auto與模板類型推導(dǎo)不一致颈畸。C++98初始化變量有兩種方式:
int x1 = 27;
int x2(27);
C++11增加了統(tǒng)一初始化語法:
int x3 = { 27 };
int x4{ 27 };
這四種初始化方式效果都一樣乌奇,把變量初始化為27。
但是如果把變量類型改成auto:
auto x1 = 27;
auto x2(27);
auto x3 = { 27 };
auto x4{ 27 };
此時眯娱,前兩個變量的類型還是int礁苗。后面兩個變量的類型變成了std::initializer_list<int>
。
這是auto推導(dǎo)規(guī)則的一個特殊的地方徙缴,如果auto的變量初始化時使用了大括號试伙,推導(dǎo)類型就是std::initializer_list
。然而于样,模板推導(dǎo)時如果使用了大括號疏叨,則推導(dǎo)失敗。
auto x = { 11, 23, 9 }; // x類型是std::initializer_list<int>
template<typename T>
void f(T param);
f({ 11, 23, 9 }); // 編譯失敗穿剖,無法推導(dǎo)出{ 11, 23, 9 }類型
如果把模板參數(shù)改為如下形式蚤蔓,則可推導(dǎo)成功:
template<typename T>
void f(std::initializer_list<T> initList);
f({ 11, 23, 9 }); // 編譯通過,initList類型是std::initializer_list<int>糊余,T是int型
因此auto和模板類型推導(dǎo)的區(qū)別在于秀又,auto會把大括號初始化推導(dǎo)為std::initializer_list单寂,模板不會。
最后吐辙,還有一點需要注意的地方宣决,C++14允許指定函數(shù)返回值為auto,C++14的lambda表達(dá)式也允許參數(shù)類型為auto昏苏。這兩種情況下的auto類型推導(dǎo)采用模板類型推導(dǎo)的規(guī)則尊沸。
因此下面兩段代碼都編譯不通過:
auto createInitList() {
return { 1, 2, 3 }; // 編譯失敗,無法推導(dǎo){ 1, 2, 3 }類型
}
std::vector<int> v;
auto resetV = [&v](const auto& newValue) { v = newValue; };
resetV({ 1, 2, 3 }); // 編譯失敗贤惯,無法推導(dǎo){ 1, 2, 3 }類型
總結(jié):
- auto類型推導(dǎo)與模板類型推導(dǎo)基本一致洼专,除了auto把大括號初始化推導(dǎo)為std::initializer_list,模板不會孵构。
- 函數(shù)返回值和lambda表達(dá)式參數(shù)中的auto采用模板類型推導(dǎo)的規(guī)則壶熏。