1.傳統(tǒng)C++ VS 現(xiàn)代C++
傳統(tǒng)C++中,參數(shù)的類型都必須明確定義,這其實對我們快速進行編碼沒有任何幫助,尤其是當我們面對一大堆復(fù)雜的模板類型時,必須明確的指出變量的類型才能進行后續(xù)的編碼,這不僅拖慢我們的開發(fā)效率,也讓代碼變得又臭又長。
C++11 引入了類型推導(dǎo),讓編譯器來操心變量的類型。這使得 C++ 也具有了和其他現(xiàn)代編程語言一樣,某種意義上提供了無需操心變量類型的使用習(xí)慣。
下面代碼中CoderWorld(1,"Traditional","C++")是傳統(tǒng)C++寫法而CoderWorld(2,"Modern","C++")是現(xiàn)代C++寫法,雖然使用了模板,但是其用法就像調(diào)用沒有使用模板的普通函數(shù)一樣,這樣的代碼明顯更加具有易讀性。這是因為C++11引入了類型推導(dǎo),編譯器會自動推導(dǎo)出參數(shù)的類型。
template
2.模板類型參數(shù)推導(dǎo)
模板類型參數(shù)推導(dǎo)共分為四種情況,下面會分別對這四種情況進行詳細闡述。
- 函數(shù)形參的類型為指針或引用類型,但不是通用引用類型
- 函數(shù)形參的類型為通用引用類型
- 函數(shù)形參的類型既不是指針也不是引用
- 數(shù)組或函數(shù)名
模板類型推導(dǎo)案例1
template<typename T>
void CoderWorld(T& param);
int x = 27;
const int& rx = x;
CoderWorld(rx); // T is const int, param's type is const int&
上述代碼中函數(shù)CoderWorld(T& param)中形參的類型是引用類型(即T&), 推導(dǎo)遵循的規(guī)則如下:
在函數(shù)形參的類型為指針或引用類型,但不是通用引用類型情況下,需要去掉實參類型中的引用(這里的去掉引用是指去掉實參類型的引用,而不是形參param的類型T&中的&)。
對于CoderWorld(rx),實參rx為const int&類型,根據(jù)上述應(yīng)該去掉實參rx 類型的引用,即將const int&中的&去掉,因此T被推導(dǎo)為const int 類型,最終param的類型T&為const int &類型。
模板類型推導(dǎo)案例2
template<typename T> void CoderWorld(T&& param);
int x = 27;
const int cx = x;
const int& rx = x;
CoderWorld(cx);//cx is lvale,so T is const int&, param's type is const int&
CoderWorld(27);//27 is rvale,so T is int,param's type is int&&
上述代碼中函數(shù)CoderWorld(T&& param) 形參類型是通用引用類型(即T&&),推導(dǎo)規(guī)則遵循如下:
在函數(shù)形參的類型為通用引用類型情況下,當實參的類型是左值時,param的類型和T的類型均為左值引用,當實參的類型是右值時,T的類型與實參一致,param的類型是實參類型的右值引用。
代碼中cx是一個左值,因此T的類型與形參param的類型均推導(dǎo)為左值引用const int &。
當CoderWorld傳入的參數(shù)是27時,因為27是右值,所以T的類型推導(dǎo)為int,param的類型推導(dǎo)為右值引用int&&
模板類型推導(dǎo)案例3
template<typename T> void CoderWorld(T param);
const int cx = x;
const int& rx = x;
CoderWorld(cx);//T and param are both int
CoderWorld(rx);// T and param are both int
上述代碼中CoderWorld(T param)形參類型T即不是指針也不是引用類型,實際上是值傳遞,也就是說這種情況下形參param是實參的一個拷貝,推導(dǎo)規(guī)則遵循如下:
在函數(shù)形參的類型既不是指針也不是引用類型的情況下,如果實參的類型有引用,則忽略掉引用部分,如果實參類型有const,則忽略掉const部分,如果有volatile也忽略掉。
代碼中實參cx的類型為const int,因此忽略掉const之后T的類型為int,形參param的類型也為int。
代碼中實參rx的類型為const int &,去掉引用和const之后T的類型為int,形參param的類型也為int。
模板類型推導(dǎo)案例4
這是一種特殊的情況,就是當實參的類型是為數(shù)組和函數(shù)的時候需要注意。C++中,數(shù)組可以退化成指針,一個函數(shù)類型也是可以退化成指針的。具體的情況如下代碼所示,結(jié)合注釋記住這段代碼中的CoderWorld1和CoderWorld2對數(shù)組和函數(shù)的推導(dǎo)情況即可。
template<typename T>
void CoderWorld1(T param);
template <typename T>
void CoderWorld2(T& param);
int arr = {0,1,2,3};
void someFunc(int,double);
CoderWorld1(arr);//arr會退化成指針,即param的類型為int*
CoderWorld2(arr);//這里很有意思,param會被推導(dǎo)為 int (&)[4]
//和上面的情況相比好處是param包含了數(shù)組的元素數(shù)量信息,可以獲取到數(shù)組的成員數(shù)。
CoderWorld1(someFunc);//param類型為函數(shù)指針 void (*)(int,double)
CoderWorld2(someFunc);//param類型為函數(shù)引用 void (&)(int,double)
3.模板類型推導(dǎo)總結(jié)
參數(shù)類型 | 例子 | 推導(dǎo)規(guī)則 |
---|---|---|
指針或引用類型,但不是通用引用類型 | template void CoderWorld(T& param);void CoderWorld(T* param); | 忽略實參引用 |
通用引用類型 | templatevoid CoderWorld(T&& param); | 實參為左值param為左值引用實參為右值param為右值引用 |
既不是指針也不是引用 | templatevoid CoderWorld(T param); | 忽略引用和const類型 |
數(shù)組或函數(shù)名 | CoderWorld(arr)CoderWorld(someFunc) | 數(shù)組退化為指針函數(shù)退化為函數(shù)指針image |
-
參數(shù)
+關(guān)注
關(guān)注
11文章
1867瀏覽量
32889 -
編碼
+關(guān)注
關(guān)注
6文章
967瀏覽量
55541 -
C++
+關(guān)注
關(guān)注
22文章
2117瀏覽量
74834
發(fā)布評論請先 登錄
C++課程資料詳細資料合集包括了:面向?qū)ο蟪绦蛟O(shè)計與C++,算法,函數(shù)等

數(shù)據(jù)結(jié)構(gòu)的各種算法實現(xiàn)資料的C++模板概述
C++之函數(shù)模板的概念及意義
c++ 之布爾類型和引用的學(xué)習(xí)總結(jié)
C++中為什么需要函數(shù)模板、類模板?
TouchGFX中Callback模板實現(xiàn)原理

C++學(xué)習(xí)筆記之c++的基本認識
C++入門之string
C++之父新作帶你勾勒現(xiàn)代C++地圖

評論