C++11 引入了 auto 和 decltype 這兩個關鍵字實現了類型推導,讓編譯器來操心變數的類型。這使得 C++ 也具有了和其他現代編程語言一樣,某種意義上提供了無需操心變數類型的使用習慣。 一. auto C++11之前:如果一個變數沒有聲明為 register變數,將自動被視為一個 au... ...
C++11 引入了
auto 和
decltype 這兩個關鍵字實現了類型推導,讓編譯器來操心變數的類型。
這使得
C++ 也具有了和其他現代編程語言一樣,某種意義上提供了無需操心變數類型的使用習慣。
一. auto
C++11之前:如果一個變數沒有聲明為 register變數,將自動被視為一個 auto 變數。
C++11開始:register 被棄用,auto賦予了其他含義,即類型自動推導。
1. 一個最為常見而且顯著的例子就是迭代器
傳統C++:
for (vector<int>::const_iterator itr = vec.cbegin(); itr != vec.cend(); ++itr) |
C++11:
for (auto itr = vec.cbegin(); itr != vec.cend(); ++itr) |
2. 一些其他的常見用法
#include
<iostream> |
註意: auto 不能用於函數傳參,因此下麵的做法是無法通過編譯的(考慮重載的問題,我們應該使用模板)
int add(auto x, auto y); |
二. decltype
decltype 關鍵字是為瞭解決 auto 關鍵字只能對變數進行類型推導的缺陷而出現的。
有時候,我們可能需要計算某個表達式的類型,例如:
auto x = 1; auto y = 2; decltype(x + y) z; |
三. 尾返回類型、auto 與 decltype 配合
1. 考慮這樣一個加法函數的例子
在傳統 C++ 中我們必須這麼寫:
template<typename R, typename T, typename U> R add(T x, U y) { return x + y } |
這樣的代碼很醜陋,因為在編寫這個模板函數的時候,必須明確指出返回類型,
但事實上我們並不知道這個函數會返回什麼類型。
2. C++11 開始這個問題得到解決
你可能馬上反應出來使用 decltype 推導x+y 的類型,寫出這樣的代碼:
decltype(x + y) add(T x, U y) |
但事實上這樣的寫法並不能通過編譯。
這是因為在編譯器讀到 decltype(x+y)時, x 和 y 尚未被定義。
3. 尾返回類型(trailing return type)
為瞭解決上面的問題,C++11 引入了一個叫做尾返回類型(trailing return type) ,
利用 auto 關鍵字將返回類型後置:
template<typename T, typename U> auto add(T x, U y) -> decltype(x + y) { return x + y; } |
C++14 函數具備返回值推導,因此下麵的寫法變得合法:
template<typename T, typename U> auto add(T x, U y) { return x + y; } |