C++11新特性:關(guān)于auto:{int i = 8; int& j = i; auto m = j;}請(qǐng)問m是什么類型?
auto其實(shí)不算一個(gè)新的關(guān)鍵字,只不過(guò)它的老的含義現(xiàn)在已經(jīng)失去了意義。
舊版 auto 的含義
在C語(yǔ)言和C++98/C++03標(biāo)準(zhǔn)中,auto是一個(gè)存儲(chǔ)類別說(shuō)明符,用于顯式地聲明一個(gè)變量具有自動(dòng)存儲(chǔ)期。這意味著變量是在進(jìn)入其作用域時(shí)創(chuàng)建,并在離開該作用域時(shí)銷毀。這是大多數(shù)局部變量默認(rèn)的行為,因此很少有人會(huì)顯式地使用auto來(lái)聲明變量,因?yàn)樗鼛缀蹩偸嵌嘤嗟摹?/span>
例如:
void function() {
auto int x = 10; // 自動(dòng)存儲(chǔ)期,實(shí)際上等價(jià)于 int x = 10;
// ...
}
在這個(gè)例子中,x 是一個(gè)具有自動(dòng)存儲(chǔ)期的局部變量。但是,因?yàn)樗芯植孔兞磕J(rèn)都是自動(dòng)存儲(chǔ)期的,所以這里的auto關(guān)鍵字是可選且冗余的。
C++11 及以后版本中的 auto
從C++11開始,auto的語(yǔ)義被完全改變,成為了一種類型推導(dǎo)機(jī)制。它允許編譯器根據(jù)初始化表達(dá)式的類型自動(dòng)推斷變量的類型。這使得代碼更加簡(jiǎn)潔,尤其是在處理復(fù)雜類型(如模板或迭代器)時(shí)。
例如:
std::vector<int> vec = {1, 2, 3};
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
在這里,auto讓編譯器推斷出it的類型應(yīng)該是std::vector<int>::iterator,從而避免了顯式寫出這個(gè)較長(zhǎng)的類型名。
我們?cè)倏搭}目中提到的問題:
int i = 8;
int& j = i;
auto m = j;
j是 int& 類型,那么m是什么類型呢?也是int&類型嗎?
答案是:m在這里是int類型而不是int& 引用類型。
auto不會(huì)保留引用特性。也就是說(shuō),auto會(huì)將j解引用,得到它所指向的實(shí)際對(duì)象的類型。
我們代碼實(shí)際操作驗(yàn)證一下:
修改后再實(shí)驗(yàn):
輸出還是int類型,這是怎么回事呢?
typeid(decltype(m)).name() 返回的類型名可能不是特別直觀,因?yàn)樗蕾囉诰幾g器的具體實(shí)現(xiàn)。不同的編譯器可能會(huì)以不同的格式返回類型名。例如,在某些編譯器中,int 類型可能顯示為 i,引用類型可能帶有額外的修飾符(如 R 表示引用)。如果需要更可讀的輸出,可能需要自己解析這些符號(hào),或者僅在調(diào)試和開發(fā)過(guò)程中使用它們。
為了更明確地確認(rèn) m 的類型是否為 int&,可以使用類型特征(type traits)來(lái)檢查。例如:
int i = 8;
int& j = i;
auto m = j;
std::cout << "Type: " << typeid(decltype(j)).name() << std::endl;
if (std::is_same<decltype(m), int&>::value) {
std::cout << "m is of type int&" << std::endl;
}
else {
std::cout << "m is not of type int&" << std::endl;
}
運(yùn)行:
修改后:
int i = 8;
int& j = i;
auto& m = j;
std::cout << "Type: " << typeid(decltype(j)).name() << std::endl;
if (std::is_same<decltype(m), int&>::value) {
std::cout << "m is of type int&" << std::endl;
}
else {
std::cout << "m is not of type int&" << std::endl;
}
輸出:
圖片
這種方法可以在編譯時(shí)進(jìn)行類型檢查,并且不會(huì)依賴于編譯器的具體實(shí)現(xiàn)。
通過(guò)上面的測(cè)試可以得到:不加引用,m在這里是int類型而不是int& 引用類型,auto不會(huì)保留引用特性。
還有同樣的 auto也不會(huì)保留const特性。
int main()
{
const int i = 9;
auto j = i;
if (std::is_same<decltype(j), const int>::value) {
std::cout << "j is of type const int" << std::endl;
}
else {
std::cout << "j is not of type const int" << std::endl;
}
return 0;
}
運(yùn)行輸出:
圖片
總結(jié):
auto不會(huì)保留引用特性。
auto不會(huì)保留const特性。