模板型別推導 auto推導

2022-03-26 14:32:42 字數 4746 閱讀 1049

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...