本文記錄了我讀Effective Modern C++時自己的一些理解和心得。
item1:模板類型推導
1)reference屬性不能通過傳值參數傳入模板函數。這就意味着如果模板函數需要一個reference類型的參數,必須在模板聲明中將其聲明為reference,否則,即使使用一個reference類型的變量調用模板函數,類型推導的結果將不帶reference屬性。
2)constant和volatile屬性也不能通過傳值參數傳入模板函數,但是可以通過reference參數傳入這些屬性。
3)如果在模板中聲明universal reference參數,那么左值參數會被推導成左值引用,右值參數會被推導成universal reference(&&)。
4)數組型變量和函數型變量會通過傳值參數推導成相應的指針型變量。而如果在模板中聲明為傳引用參數,則會被推導成數組引用(包含數組大小信息)和函數引用。
item2:auto類型推導
1)auto類型推導規則和模板類型推導規則相同,除了處理以{}初始化的參數的情況。
2)模板不能推導被{}初始化的參數,除非將它聲明為std::initializer_list<T>類型的參數。
#include <iostream>
template<typename T>
void f1(T param) { return; }
template<typename T>
void f2(std::initializer_list<T> param) { return; }
int main()
{
auto i = { 1, 2, 3, 4 };
f1(i); // good
//f1({ 1, 2, 3, 4 }); //error
f2({ 1, 2, 3, 4 }); //good
return 0;
}
3)在C++14中,返回值為auto類型的函數不得返回以{}初始化的值。lambda函數的auto類型參數也不能以{}初始值作為參數調用。
auto f1() { return 4; } //good
auto f2() { auto i = {1,2,3,4}; return i; } //good
error auto f3() { return {1,2,3,4}; } //error
item3:理解decltype
1)decltype不加任何修改地返回參數的類型
2)decltype的典型應用是保持左值的引用屬性
item4 :如何查看推導類型
1)方法有:從IDE編輯器查看,編譯錯誤診斷,運行時輸出。
2)std::type_info容易出錯,推薦使用boost::typeindex。
item5:推薦使用auto,而不是顯式聲明類型
1)使用auto可以確保變量被初始化。
2)使用auto可以避免因為隱式的類型轉換而生成臨時變量。
3)使用auto可以確保類型一定是對的,例如size()的類型和迭代器(iterator)的類型。
4)使用auto使代碼簡潔。
item6:哪些地方不要用auto
1)特殊的數據類型,例如std::vector<bool>。凡是有看不見的代理類(invisiable proxy class)的情況都要慎用auto。
2)需要顯示指定類型的推薦用法是:
auto x = static_cast<type>(initializer)
這樣可以明確表示此處發生了類型轉換。
<未完待續>