日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++11新增的关键字decltype(auto)

發布時間:2024/4/17 c/c++ 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++11新增的关键字decltype(auto) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、函數模板存在的類型問題

template<class T1,class T2> void fun(T1 a, T2 b) {(T1 or T2?)y = a + b; }

語句y = a+b,其實我們并不知道y應該為什么類型,我們可以寫成T1或者T2甚至可能是其類型。但是具體準確的寫成哪一個呢?我們并不確定,因為用函數模板產生函數實體跟傳入實參的類型有關,如果我們調用的時候是fun(int, double)那么按道理來說,結果應該是double,當然,如果我們用T1(在這里即int)也可以接收,只不過降低了結果的精確度。如果調用的時候是fun(short, int)那么結果準確類型的話,就是int類型的。甚至如果我們調用函數時fun(char , short),那么結果準確類型應該是int類型(在這里加法運算會導致自動整數提升),這個時候既不是T1類型,也不是T2類型。除此之外,我們可能重載結構體或者類的"+"運算符,這會導致結果的類型更復雜多變。
C++11提出decltype關鍵字來解決這個問題。

二、decltype關鍵字

1.decltype基本用法和作用

int main() {int x = 10;decltype(x) y1;//int類型short a = 2;char b = 1;decltype(a + b) y2;//int類型double c = 1;decltype(x + c) y3;//double類型return 0; }

相當于decltype會自動推演類型,這一點我覺得和auto挺相像的。
那么我們的模板類就可以寫成下面這樣。

template<class T1,class T2> void fun(T1 a, T2 b) {decltype(a+b) y = a + b; }

這樣y類型就是精確的類型了。
即decltype的使用格式是:decltype (expression) y;即定義一個變量y,類型和expression類型相同。expression可以是變量也可以是表達式。
編譯器為了確定類型,會遍歷一個核對表。

(1)如果expression是一個沒有用括號括起來的標識符,則y與這個標識符類型相同。
舉例:
int a;
decltype(a) y;
那么y就是和a類型相同,是int類型,包括const限定符。
舉例:
const int a = 10;
decltype(a) y = 20;
decltype(a) y2(20);
注意上面decltype兩種用法都可,但是一定得給初始值,因為y和y2也是const int類型,所以一定得給初始值。
(2)如果expression是一個左值并且用括號括起來了,那么y是這個標識符類型的引用。
舉例:
int a;
decltype ((a)) y1(x1);
const int b = 10;
decltype((b)) y2(x2);
注意在這里y1就是類型為int& 類型的變量,x1是給y1初始化的,x1一定是個左值,且肯定不能是const。y2是類型為const int& 類型的變量,x2是給y2初始化的。
總結來說,expression再加個括號,那么decltype定義的變量類型就是expression類型的引用。引用我們都知道,一定需要初始化,初始化規則和我們平常使用引用初始化規則都一樣。
(3)如果expression是一個函數調用,那么y與函數返回值類型相同,注意在這里并沒有實施調用函數,只是編譯器根據函數返回值類型推出來變量y應該的類型。
舉例:
int fun(){return 0;}
decltype(fun()) y1;
decltype((fun())) y2;
注意y1和y2都是與fun函數返回類型相同的類型,即int。并不會因為多加了括號而變成int&。也就是上面的第二點對于函數并不適用。
(4)如果上面的都不符合,那么y和表達式expression類型相同。
舉例:
int a = 10;
int& b = a;
int& c = a;
float d = 10;
decltype(a+b) y1;
decltype(b+c) y2;
decltype(a+d) y3;
a+b為int類型,所以y1是int類型。
b+c也是int類型,所以y2是int類型。
a+d是float類型,所以y3是float類型。
模板函數內部的變量類型用C++11新增的關鍵字decltype解決了。但是函數返回類型呢?
比如:

template<class T1,class T2> ? fun(T1 a,T2 b) {return x + y; }

函數返回值類型是什么?我們并不確定,剛才講了decltype,難道可以這樣寫?:

template<class T1,class T2> decltype(x+y) fun(T1 a,T2 b) {return a + b; }

答案是不行!因為此時還沒有執行函數體,還不知道x和y變量,編譯器看不見x和y,沒辦法使用。我們可以用auto。在這里auto是一個占位符,表示后置返回類型提供的類型。編譯器會在編譯期間將auto替換為正確類型。而decltype是關鍵字。這也是它們倆的不同點。

template<class T1,class T2> auto fun(T1 a,T2 b)->decleype(x+y) {return a + b; }

這種寫法是我在書上看的,但是我們其實不用這么麻煩,可以直接這樣寫:

template<class T1,class T2> auto fun(T1 a,T2 b) {return a + b; }

因為auto是占位符,沒有什么其他特殊作用,是編譯器編譯期間推導出來類型,將auto替換為了正確推導出來的類型。auto除了占位這個作用,其他事情都是編譯器做的。
其實我們前面說的decltype做的事情,我們可以用auto占位,讓編譯器編譯期間將auto替換掉。
比如:
int a = 10;
float b = 20;
auto x1 = a;
auto x2(a+b);
auto x2 = (a+b);
發現auto可以基本替代掉decltype的作用。只不過定義變量使用auto占位時,必須給出變量的初始值或者表達式,這樣編譯器才會有推導變量類型的依據,才能用正確類型替換掉占位符auto。

總結

以上是生活随笔為你收集整理的C++11新增的关键字decltype(auto)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。