C++学习笔记35:函数模板
生活随笔
收集整理的這篇文章主要介紹了
C++学习笔记35:函数模板
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
函數模板
函數模板的目的
- 設計通用的函數,以適應廣泛的數據型式
函數模板的定義格式
- template<模板型式參數列表>返回值型式 函數名稱(參數列表);
- 原型:template<class T> void Swap(T &a, T&b);
- 實現:template<class T> void Swap(T &a , T&b){...}
函數模板的體化與特化
- 針對特定型參數,在聲明或第一次調用該函數模板時體化
- 每次體化都形成針對特定型參數的重載函數版本
- 文件最終只保留特定型參數的一份體化后的函數
- 顯式體化主要用于庫的設計;顯式特化覆蓋體化的同型函體
?
//函數模板
template<class T> void f(T t) {/* */}
//顯式體化:使用顯式的長整型模板參數
template void f<long>(long n);
//顯式體化:使用d的型式推導模板參數型式
template void f(double d);
//顯式特化:使用顯式的整型參數
template<> ?void f<int> (int n);
//顯式特化:使用c的型式推導模板參數型式
template<> void f(char c);
template <class T> void Swap(T &a, T &b) {T a; t = a, a = b, b = t; } int main() {int m = 11, n = 7;char a = 'A', b = 'B';double c = 1.0, d = 2.0;//正確調用,體化Swap(int &,int &) Swap(m, n);//正確調用,體化Swap(char &,char &)Swap<char>(m, n);//正確調用,體化Swap(double &, double &)Swap<double>(c, d);return 0; }?
函子
編寫函數,求某個數據集的最小元,元素型式為T
- 實現策略:使用函數指針作為回調函數參數
- 實現策略:使用函子(function object, functor)作為回調函數參數
函數指針實現
//const T *a 指向數據集的基地址 //n為元素的個數 template<typename T> const T &Min(const T *a, int n, bool(*compare)(const T&, const T&)) {int index = 0;for (int i = 1; i < n; i++){if (comparer(a[i], a[index]))index = i;}return a[index]; }?
函子
函子的目的
功能上:類似函數指針
實現上:重載函數調用操作符,必要時重載小于比較操作符
函子的優點
函數指針不能內聯,而函子可以,效率更高
函子可以擁有任意數量的額外數據,可以保證結果和狀態,提高代碼的靈活性
編譯時可對函子進行型式檢查
函子實現
//使用方法
int a[8] = {9,2,3,4,5,6,7,8};
int min = Min(a,8,Comparer<int>());//構造匿名函子作為函數參數
template<typename T>class Comparer { public://確保型式T已存在或重載operator<bool operator()(const T &a, const T &b){return a < b;} };template<typename T,typename Comparer> const T &Min(const T *a, int n, Comparer comparer) {int index = 0;for (int i = 1; i < n; i++){if (comparer(a[i], a[index]))index = i;}return a[index]; }完美轉發
完美轉發的意義
- 庫的設計者需要設計一個通用的函數,將接受到的參數轉發給其他函數
- 轉發過程中,所有參數保持原先的語義不變
完美轉發的實現策略
- 當需要同時提供移動語義和拷貝語義時,要求重載大量建構函數,編程量大,易出錯
- 右值引用與函數模板相互配合,可以實現完美轉發,極大降低代碼編寫量
例子:
class A { public:A(const string &s, const string &t) :_s(s), _t(t) {}A(const string &s, string && t) :_s(s), _t(move(t)) {}A(string &&s, const string &t) :_s(move(s)), _t(t) {}A(string &&s, string &&t) :_s(move(s)), _t(move(t)) {} private:string _s, _t; }; int main() {string s1("Hello");const string s2("World");A a1(s1, s2);A a3(string("Good"), s2);A a2(s1, string("Bingo"));A a4(string("Good"), string("Bingo"));return 0; }改進后:
class A { public://根據實際參數型式生成不同的左值或右值引用的建構函數版本//T1或T2可以不同型,此處相同僅為示例//實參推演時,使用引用折疊機制//當形式參數為T&&型時,當且僅當實際參數為右值或者右值引用時//實際參數型式才為右值引用//引用折疊機制與const/volatile無關,保持其參數性質不變//std::forward<T>(t)轉發參數的右值引用T&& template<typename T1, typename T2> A(T1 &&s, T2 &&t):_s(std::forward<T1>(s)), _t(std::forward<T2>(t)) {} private:std::string _s, _t; };?
轉載于:https://www.cnblogs.com/hujianglang/p/6260741.html
總結
以上是生活随笔為你收集整理的C++学习笔记35:函数模板的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑启动lol卡怎么办 电脑开LOL卡顿
- 下一篇: win10系统装win7系统怎么安装教程