最近在惡補 C++ 知識的時候,學習到了一些 C++11 標準的新特性,利用這些新特性,我們能夠更快地提高編程效率,從而實現我們的目標,在此特意記下學習過程中所學習到的一些東西,方便日後的回顧和複習。
auto 關鍵字
在我們日常編程的時候,我們常常需要把表達式的值賦給變量,需要在聲明變量的時候,我們必須清楚的知道變量是屬於什麼類型的。然而往往有些時候,我們做到這一點並非易事。爲了解決這個問題, C++11 新標準就引入了 auto 類型說明符,通過使用 auto 關鍵字,我們就能讓編譯器替我們去分析表達式所屬的類型,和原來那些只對應某種特定的類型說明符(例如 int )不同, auto 能讓編譯器通過初始值來進行類型推演,從而獲得定義變量的類型,這樣一來,我們就可以大大地降低我們在編程中出現變量類型錯誤的概率了。
需要注意的一點⚠️:auto 定義的變量必須有初始值。
舉個例子:
#include <iostream>
#include <typeinfo>
using namespace std;
int main(int argc, const char *argv[])
{
auto value1 = 1;
auto value2 = 2.33;
auto value3 = 'a';
std::cout << "value1 的類型是 " << typeid(value1).name() << std::endl;
std::cout << "value2 的類型是 " << typeid(value2).name() << std::endl;
std::cout << "value3 的類型是 " << typeid(value3).name() << std::endl;
return 0;
}
運行結果如下:
value1 的類型是 i
value2 的類型是 d
value3 的類型是 c
注: typeid() 操作符可以輸出變量的類型,其庫函數在
頭文件中,如上面👆這個例子所示。
編譯器推斷出來的 auto 類型有時候會跟初始值的類型並不完全一樣,編譯器會適當的改變結果類型,使得其更符合初始化規則。例如我們平常用的浮點數類型 float 和 double ,編譯器似乎會優先選擇 double 類型。
但 auto 需要注意的一點就是,使用 auto 能在一個語句中聲明多個變量,但是一個語句在聲明多個變量的時候,只能有一個基本數據類型,所以該語句中所有變量的初始基本數據類型都必須是一樣的。在這裏一定要區別數據類型和類型修飾符!!
例如:
我們在上面代碼中增加 value4 和 value5:
auto value4 = "QAQ", value5 = &value1;
我們可以看到,在編譯時出現了報錯,原因是因爲 value4 推斷出的類型是字符串型,而 value5 推斷出來的類型是指針類型,一條語句在聲明多個變量的時候,只能有一個基本數據類型,所以會有如下的錯誤出現。
decltype 關鍵字
而 decltype 類型說明符也是 C++11 的標準,它是用於從表達式的類型推斷出要定義的變量的類型。
因爲在有些時候,我們會遇到如下這種情況:
我們希望從表達式中推斷出要定義變量的類型,但卻不想用表達式的值去初始化變量,或者當函數的返回值類型爲某表達式的值的類型,這個時候, auto 顯得就很無力了,所以 C++11 又引入了第二種類型說明符 decltype 。它的作用是選擇並返回操作數的數據類型。在此過程中,編譯器只是分析表達式或函數的返回值的類型並得到它的類型,卻不進行實際的計算表達式的值。
舉個例子:
#include <iostream>
#include <typeinfo>
using namespace std;
std::string func(){
return "Hello World!";
}
int main(int argc, const char *argv[])
{
decltype(func()) a;
int i;
decltype(i) b;
std::cout << "a 的類型是 " << typeid(a).name() << std::endl;
std::cout << "b 的類型是 " << typeid(b).name() << std::endl;
return 0;
}
輸出結果如下:
a 的類型是 NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE
b 的類型是 i
注:decltype()括號中的表達式並不去執行,而 decltype((variable)) 的結果永遠是引用,而 decltype((variable)) 只有當 variable 本身是一個引用是纔是引用。
auto 關鍵字和 decltype 關鍵字的區別
對於 decltype 所用的表達式來說,如果變量名加上一對括號,則得到的類型與不加上括號的時候可能不同。
如果 decltype 使用的是一個不加括號的變量,那麼得到的結果就是這個變量的類型。但是如果給這個變量加上一個或多層括號,那麼編譯器會把這個變量當作一個表達式看待,變量是一個可以作爲左值的特殊表達式,所以這樣的decltype就會返回引用類型。
如:
int i;
decltype(i) // int類型
decltype((i)) // int& 類型
在這裏我們不探討太多的一些具體的細節,只介紹一些常用的一些用法和注意事項,想了解更多的話參考 C++ Primer Plus 。