C++ 11 模板函式的預設模板引數
阿新 • • 發佈:2018-12-24
關於預設的函式引數,有一條規則:
void defFunc(int i ,int j = 2,int k = 3) {
}
那就是預設實參必須在形參的右邊.
為什麼要這麼規定? 其實我們呼叫一下程式碼就可以發現,必須這樣:
defFunc(1); 預設等於 defFunc(1,2,3)
defFunc(1,8); 預設等於 defFunc(1,8,3)
如果不把預設實參放到形參的右邊,那麼我們的函式很可能就是:
defFunc("預設引數" ,2,3)
很顯然我們就得引入一個標誌,告訴編譯器這裡是一個預設引數.
今天我們要重點講的是,函式模板和類模板預設模板引數型別的規則:
C++98開始支援引入函式模板和類模板,並且支援類模板的預設型別,但是C++98這個時候還不支援,函式模板預設型別. C++ 11引入了此規則.
template <typename T = int> void defFunc(T a) { //C++ 98不合法,C++ 11合法
}//可以這麼寫,但是沒有什麼意義,呵呵!自己想.
類模板預設引數型別和函式預設引數擁有一樣的規則:預設實參型別必須在形參的右邊.
template<class T, class T1 = int, class T2 = string> class myclass{ //合法 };
以下寫法是不合法的.
template<class T = int, class T1 , class T2 = string> class myclass2 { //不合法
};
原因其實和預設函式引數實參型別必須在形參右邊是一樣的。
類模板本身是一個大家族,模板類是一個具體的大家族中的成員,類似具體下面模板類的寫法:
myclass<int ,double ,string> m1;
只是
myclass<T1,T2,T3>類模板中的一員而已.
和函式同樣的理由,如果不這麼做,那麼我們可以就必須引入一個標誌,告訴編譯器這是個預設型別,那麼就失去預設型別的意義了.
但是再想想,為什麼函式引數卻不需要遵守這個規則了呢??
肯定是由於某種原因,導致了此規則被破壞.
答案是:函式模板引數型別,編譯器支援預設型別的推導。
舉個例子:
template<typename T1, typename T2> void func(T1 t1, T2 t2) {
cout << t1 << endl;
cout << t2 << endl;
}
編譯器能夠根據函式的引數型別自動推匯出模板函式,但是模板類就不行,編譯器沒法自動幫模板類做引數型別的匹配。
下面的模板函式,預設引數型別就是
template<typename T1 = int, typename T2, typename T3> void func2(T2 t2,T3 t3,T1 t1 = 0) {
cout << t1 << endl;
cout << t2 << endl;
cout << t2 << endl;
}
在函式中,可以看到預設的模板型別是不需要遵守必須在右邊的規定的.
因為編譯器也能夠很輕鬆的推匯出。