1. 程式人生 > >類型別名,auto,decltype

類型別名,auto,decltype

1、類型別名

  類型別名是某種型別的同義詞。

1 int main()
2 {
3     typedef char *ps; // ps是型別char*的別名
4     const ps p1 = 0; // p1是指向char的常量指標
5     const ps *p2; // p2是一個指標,它的物件是指向char的常量指標
6     return 0;
7 }

注意:遇到使用了類型別名的宣告語句時,人們往往會錯誤地嘗試把類型別名替換成它本來的樣子去理解,這種理解方法是錯誤的;要將類型別名看成是一個基本資料型別去理解。

2、auto型別說明符

  使用auto型別說明符能讓編譯器替我們去分析表示式所屬的型別。編譯器推斷出來的

auto型別有時候和初始值的型別並不完全一樣,編譯器會適當地改變結果型別使其更符合初始化規則。

 

 1 int main()
 2 {
 3     /*
 4     當引用被用作初始值時,真正參與初始化的其實是引用的物件的值,
 5     此時編譯器以引用物件的型別作為auto的型別。
 6     */
 7     auto i = 0, &r = i;
 8     auto a = r; // a是一個整數
 9     /*
10     auto一般會忽略掉頂層const,底層const會保留下來
11     */
12     const int ci = i, &cr = ci;
13 auto b = ci; // b是一個整數(ci的頂層const特效被忽略掉了) 14 auto c = cr; // c是一個整數(cr是ci的別名,ci本身是一個頂層const) 15 auto d = &i; // d是一個整型指標 16 auto e = &ci; // e是一個指向常量的指標(對常量物件取地址是一種底層const) 17 /* 18 如果希望推斷出的auto型別是一個頂層const,需要明確指出 19 */ 20 const auto f = ci; // ci的推演型別是int,f是const int 21
/* 22 可以將引用的型別設為auto,此時原來的初始化規則仍然使用;設定一個型別 23 為auto的引用時,初始值中的頂層const仍然保留。如果我們給初始值繫結一個引用, 24 則此時的常量就不是頂層const了。 25 */ 26 auto &g = ci; // g是一個整型常量引用,繫結到ci 27 //auto &h = 42; // 錯誤:不能為非常量引用繫結字面值 28 const auto &j = 42; // 可以為常量引用繫結字面值 29 return 0; 30 }

 

3、decltype型別說明符

  decltype的作用是選擇並返回運算元的資料型別。在此過程中,編譯器分析表示式並得到它的型別,卻不實際計算表示式的值。

  如果decltype使用的表示式是一個變數,則decltype返回該變數的型別(包括頂層const和引用在內)。

 

1 int main()
2 {
3     const int ci = 0, &cj = ci;
4     decltype(ci) x = 0; // x的型別是const int
5     decltype(cj) y = x; // y的型別是const int &,y繫結到變數x
6     //decltype(cj) z; // 錯誤:z是個引用,必須初始化
7     return 0;
8 }

 

  如果decltype使用的表示式不是一個變數,則decltype返回表示式結果對應的型別。有些表示式將向decltype返回一個引用型別。一般來說,當這種情況發生時,意味著該表示式的結果物件能作為一條賦值語句的左值。如果表示式的內容是解引用操作,則decltype將得到引用型別。

 

1 int main()
2 {
3     int i = 42, *p = &i, &r = i;
4     decltype(r + 0) b; // 加法的結果是int,因此b是一個未初始化的int
5     //decltype(*p) c; // 錯誤:c是int&,必須初始化
6     return 0;
7 }

 

  對於decltype所用的表示式來說,如果變數名加了一對括號,則得到的型別和不加括號時會有不同。如果decltype使用的是一個不加括號的變數,則得到的結果就是該變數的型別;如果給變數加上了一層或多層括號,編譯器就會把它當成是一個表示式。變數是一種可以作為賦值語句左值的特殊表示式,所以這樣的decltype就會得到引用型別。

 

1 int main()
2 {
3     int i = 42;
4     //decltype((i)) d; // 錯誤:d是int&,必須初始化
5     decltype(i) e; // e是一個未初始化的int
6     return 0;
7 }