002 模板实参推断、重载与模板
模板實(shí)參推斷
一、模板函數(shù)顯示實(shí)參
情況1:
template <typename T1, typename T2, typename T3> T1 sum(T2 a, T3 b) {return a + b; }分析:調(diào)用的時(shí)候就需要指定T1的類型,如:sum<float>(1, 2); 于是sum函數(shù)的返回類型為float。
?
?情況2:
template <typename T1, typename T2, typename T3> //糟糕的設(shè)計(jì),用戶必須指定所有的三個(gè)模板參數(shù) T3 sum(T1 a, T2 b) {return a + b; }分析:對(duì)于sum<float>(1, 2); 現(xiàn)在這個(gè)調(diào)用里指定T1類型為float,但是實(shí)際傳進(jìn)來(lái)的是1(int類型),會(huì)進(jìn)行隱式類型轉(zhuǎn)換,將1轉(zhuǎn)換為float.?T2的類型也可以根據(jù)sum(1,2)調(diào)用的第二個(gè)實(shí)參推斷出來(lái),這里是可能會(huì)是int. 那么T3是什么類型呢?顯然這里編譯器無(wú)法推斷T3的類型,需要在調(diào)用時(shí)指定才能推斷:
1. ??sum<int,?int,?int>(1,?2);?這樣T3就推斷出來(lái)是int。?
2. 在指定顯示模板實(shí)參時(shí)指定的類型是和模板參數(shù)匹配的,順序是一一對(duì)應(yīng)的,如:
? ? ???使用 sum<int>(1, 2); 對(duì)上面的第一個(gè)模板進(jìn)行調(diào)用,那么T1對(duì)應(yīng)int,T2和T3則通過(guò)推斷得出。
? ? ???使用 sum<int>(1, 2); 對(duì)上面的第二個(gè)模板進(jìn)行調(diào)用,那么T1對(duì)應(yīng)的類型是int,T2可以根據(jù)實(shí)際穿進(jìn)去的參數(shù)進(jìn)行推斷,這里2為int,那么T2類型就是int,那么編譯器就無(wú)法知道T3的實(shí)際類型了。
?
?二、完美轉(zhuǎn)發(fā)
template<class T> void wrapper(T&& arg) {// arg 始終是左值foo(std::forward<T>(arg)); // 轉(zhuǎn)發(fā)為左值或右值,依賴于 T } 分析:1. 若對(duì) wrapper() 的調(diào)用傳遞右值string ,則推導(dǎo) T 為 std::string(非string& 或string&& ,且 std::forward 確保將右值引用傳遞給 foo.2. 若對(duì) wrapper() 的調(diào)用傳遞 const 左值string ,則推導(dǎo) T 為 const string& ,且 std::forward 確保將 const 左值引用傳遞給 foo.3. 若對(duì) wrapper() 的調(diào)用傳遞非 const 左值string ,則推導(dǎo) T 為string& ,且 std::forward 確保將非 const 左值引用傳遞給 foo.?分析:
1. 若對(duì) wrapper() 的調(diào)用傳遞右值string ,則推導(dǎo) T 為 std::string(非string& 或string&& ,且 std::forward 確保將右值引用傳遞給 foo.
2. 若對(duì) wrapper() 的調(diào)用傳遞 const 左值string ,則推導(dǎo) T 為 const string& ,且 std::forward 確保將 const 左值引用傳遞給 foo.
3. 若對(duì) wrapper() 的調(diào)用傳遞非 const 左值string ,則推導(dǎo) T 為string& ,且 std::forward 確保將非 const 左值引用傳遞給 foo.
?舉例
1 #include<iostream> 2 #include<utility> 3 using namespace std; 4 5 void g(int &&i, int &j) 6 { 7 cout << i << " " << j << endl; 8 } 9 10 void f(int v1, int &v2) 11 { 12 cout << v1 << " " << ++v2 << endl; 13 } 14 15 //flip1實(shí)現(xiàn)不完整:頂層const和引用都丟掉了 16 template <typename F, typename T1, typename T2> 17 void flip1(F f, T1 t1, T2 t2) 18 { 19 f(t2, t1); 20 } 21 22 template <typename F, typename T1, typename T2> 23 void flip2(F f, T1 &&t1, T2 &&t2) 24 { 25 f(t2, t1); 26 } 27 28 template <typename F, typename T1, typename T2> 29 void flip(F f, T1 &&t1, T2 &&t2) 30 { 31 f(std::forward<T2>(t2), std::forward<T1>(t1)); 32 } 33 34 int main() 35 { 36 int i = 0, j = 0, k = 0, l = 0; 37 cout << i << " " << j << " " << k << " " << l << endl; 38 f(42, i); //f改變其實(shí)參i 39 flip1(f, j, 42); //通過(guò)flip1調(diào)用f不會(huì)改變j 40 flip2(f, k, 42); //正確:k被改變了 41 g(42, i); 42 flip(g, i, 42); //正確:第三個(gè)參數(shù)的右值屬性被保留了 43 cout << i << j << " " << k << " " << l << endl; 44 return 0; 45 }?
重載與模板
轉(zhuǎn)載于:https://www.cnblogs.com/sunbines/p/9375847.html
總結(jié)
以上是生活随笔為你收集整理的002 模板实参推断、重载与模板的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SQLServer数据库(二)
- 下一篇: 一块冰西瓜险丧命?这种吃法很危险 很多人