我的主力博客:半畝方塘
一、類型別名
有兩種方法可以定義類型別名:
typedef double wages; // wages 是 double 的同義詞
typedef wages *p; // p 是 double* 的同義詞
新標准規定了一種新的方法:
using SI = Sales_item; // SI 是 Sales_item 的同義詞
類型別名和類型名等價,只要是類型的名字能出現的地方,就能使用類型別名
如果某個類型別名指代的是復合類型或常量,那麼把它用在聲明語句裡就會產生意想不到的後果:
typedef char *pstring;
const pstring cstr = 0; // cstr 是指向 char 的常量指針
const pstring *ps; // ps 是一個指針,它的對象是一個指向 char 的常量指針
const char *cstr = 0; // 是對 const pstring cstr = 0 的錯誤理解
二、auto 類型說明符
C++ 新標准引入了 auto 類型說明符,用它就能讓編譯器替我們去分析表達式所屬的類型,使用 auto 也能在一條語句中聲明多個變量,因為一條聲明語句只能有一個基本數據類型,所以語句中所有變量的初始基本數據類型都必須一樣:
auto i = 0, *p = &i; // 正確,i 是整數,p 是整型指針
auto sz = 0, pi = 3.14; // 錯誤,sz 和 pi 的類型不一致
int i = 0, &r = i;
auto a = r; // a 是一個整數,當引用被用作初始值時,真正參與初始化的其實是引用對象的值
auto 一般會忽略掉頂層 const,同時底層 const 則會保留下來:
const int ci = i, &cr = ci;
auto b = ci; // b 是一個整數(ci 的頂層 const 特性被忽略掉了)
auto c = cr; // c 是一個整數
auto d = &i; // d 是一個整型指針
auto e = &ci; // e 是一個指向整數常量的指針(對常量對象取地址是一種底層 const )
如果希望推斷出的 auto 類型是一個頂層 const,需要明確指出:
const auto f = ci; // ci 的推演類型是 int, f 是 const int
還可以將引用的類型設為 auto,此時原來的初始化規則仍然適用:
auto &g = ci; // g 是一個整型常量引用,綁定到 ci
auto &h = 42; // 錯誤,不能為非常量引用綁定字面值
const auto &j = 42; // 正確,可以為常量引用綁定字面值
要在一條語句中定義多個變量,切記,符號 & 和 * 只從屬於某個聲明符,而非基本數據類型的一部分,因此初始值必須是同一種類型:
auto k = ci, &l = i; // k 是整數,l 是整型引用
auto &m = ci, *p = &ci; // m 是對整型常量的引用,p 是指向整型常量的指針
auto &n = i, *p2 = &ci; // 錯誤,i 的類型是 int 而 &ci 的類型是 const int
三、decltype 類型指示符
C++11 新標准引入了 decltype,它的作用是選擇並返回操作數的數據類型,但並不實際計算表達式的值,如果使用的表達式是一個變量,則 decltype 返回該變量的類型(包括頂層 const 和引用在內):
const int ci = 0, &cj = ci;
decltype(ci) x = 0; // x 的類型是 const int
decltype(cj) y = x; // y 的類型是 const int&,y 綁定到變量 x
decltype(cj) z; // 錯誤,z 是一個引用,必須初始化
int i = 42, *p = &i, &r = i;
decltype(r + 0) b; // 正確,加法的結果是 int
decltype(r) b; // 結果是引用類型
decltype(*p) c; // 錯誤,c 是 int&,必須初始化
如果表達式的內容是解引用操作,則 decltype 將得到引用類型,如上面的 decltype(*p) c;
,c
就是一個引用類型
decltype 的結果與表達式的形式密切相關,對於 decltype 所用的表達式來說,如果變量名加上了一對括號,則得到的類型與不加括號時有所不同:
// decltype 的表達式如果是加上了括號的變量,結果將是引用
decltype((i)) d; // 錯誤,d 是 int&,必須初始化
decltype(i) e; // 正確,e 是一個未初始化的 int
切記:decltype((variable))(注意是雙層括號)的結果永遠是引用,而 decltype(variable)結果只有當 variable 本身就是一個引用時才是引用