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

C++之函數模板的概念及意義
c++ 之布爾類型和引用的學習總結
C++中為什么需要函數模板、類模板?
TouchGFX中Callback模板實現原理

評論