effective modern c++ 果然是神書,乾貨滿滿,簡單記錄下。
item1 模板推倒
典型的模板函式
temlate
void fn(paramtype param)
要記住的東西
在模板型別推導的時候,有引用特性的引數的引用特性會被忽略
在推導通用引用引數的時候,左值會被特殊處理
在推導按值傳遞的引數時候,const
和/或volatile
引數會被視為非const
和非volatile
在模板型別推導的時候,引數如果是陣列或者函式名稱,他們會被退化成指標,除非是用在初始化引用型別
當paramtype 是指標或者引用時,
如果expr
的型別是個引用,忽略引用的部分。
然後利用expr
的型別和paramtype
對比去判斷t
的型別。
templatevoid f(t& param); //param是乙個引用型別
int x = 27; //
x是乙個int
const
int cx = x; //
cx是乙個const int
const
int& rx = x; //
rx是const int的引用
f(x);
//t是int,param的型別時int&
f(cx);
//t是const int,
//param的型別是const int&
f(rx); //
t是const int
//param的型別時const int&
當paramtype 是右值引用時,(注意到param是左值時的特殊性)
templatevoid f(t&& param); //param現在是乙個通用的引用
int x = 27; //
和之前一樣
const
int cx = x; //
和之前一樣
const
int& rx = x; //
和之前一樣
f(x);
//x是左值,所以t是int&
//param的型別也是int&
f(cx);
//cx是左值,所以t是const int&
//param的型別也是const int&
f(rx);
//rx是左值,所以t是const int&
//param的型別也是const int&
f(27); //
27是右值,所以t是int
//所以param的型別是int&&
當paramtype 既不是指標也不是引用時,按照pass by value 來
和之前一樣,如果expr
的型別是個引用,將會忽略引用的部分。
int x = 27; //和之前一樣
const
int cx = x; //
和之前一樣
const
int& rx = x; //
和之前一樣
f(x);
//t和param的型別都是int
f(cx);
//t和param的型別也都是int
f(rx);
//t和param的型別還都是int
最後再來個大殺器
//陣列的引用再理解下
//int a= --> a的型別是啥? int [3]
//int & rb --->rb的型別是啥? rb先與&結合,表明是個引用,然後接觸int 表明是個int型的引用
//int (&ra)= -->ra的型別是啥? ra先與&結合,表明是個引用,然後接觸 int [3] 是個int [3] 的引用
//那如果去掉ra的形參,如何寫呢 int (&) [3] ,這是個型別,並且是int [3] 的引用
//計算陣列長度 constexpr需要vs2015以上
templateconstexpr std::size_t constarraysize(t(&)[size])
template
std::size_t arraysize(t(&)[size])
item2 auto 推導
能夠理解item1的話,這個就好辦了,這個和item1的推導幾乎一模一樣。
item1的關鍵有個t 和paramtype 需要推導,對於auto來說,t就是auto!這麼說有點困難,我們例子來說明
auto x = 27; //t 是auto paramtype也是auto 即item1上的規則3,pass by value
const auto cx = x; //t 是auto paramtype是 const auto ,按照規則3
auto& rx = x; //t 是auto paramtype是 auto & 按照規則1
auto&& uref1 = x; //x是int並且是左值
//所以uref1的型別是int&
auto&& uref2 = cx; //
cx是int並且是左值
//所以uref2的型別是const int&
auto&& uref3 = 27; //
27是int並且是右值
//所以uref3的型別是int&&
const
char name = //
name的型別是const char[13]
"r. n. briggs";
auto arr1 = name; //
arr1的型別是const char*
auto& arr2 = name; //
arr2的型別是const char (&)[13]
void somefunc(int, double); //
somefunc是乙個函式,型別是
//void (*)(int, double)
auto& func2 = somefunc; //
func1的型別是
//void (&)(int, double)
到此為止,我們都非常成功,接下來是auto 與模板推導不同的地方
auto x1 = 27; //型別時int,值是27
auto x2(
27); //
同上auto x3 = ; //
型別是std::intializer_list
//值是
auto x4; //
同上auto x5 = ; //
錯誤! 不能講t推導成
//std::intializer_list
auto x = ; //
x的型別是
//std::initializer_list
template
//和x的宣告等價的
void f(t param); //
模板f(); //
錯誤的!沒辦法推導t的型別
template
void f(std::initializer_listinitlist);
f(); //
t被推導成int,initlist的
//型別是std::initializer_list
要記住的東西
auto
型別推導通常和模板型別推導類似,但是auto
型別推導假定花括號初始化代表的型別是std::initializer_list
,但是模板型別推導卻不是這樣
auto
在函式返回值或者lambda引數裡面執行模板的型別推導,而不是通常意義的auto
型別推導
模板型別推導
param引用無const修飾template void f t param int x 1 const int cx x const int rx x f x f cx f rx 函式呼叫 t的型別 param的型別 f x intint f cx const int const int f rx...
C 模板型別推導
內容參考 effective modern c 中的條款1 int x 27 const int cx x const int rx x const int p x 1.paramtype是個指標或引用,但不是個萬能引用 去引用不去const template void f t param f x ...
C 11 14 自動型別推導 auto
從c 11起,auto關鍵字不再表示儲存型別,而是成為了隱式型別定義關鍵字,其作用是讓編譯器在編譯期 便自動推斷出變數的型別。例如 auto a 1 a 為 int 型變數 auto ptr new auto 1 auto 1 int 1 ptr 為 int 型指標變數 const auto q a...