(C++模板程式設計):通過遞迴組合、tuple及基類引數包展開引數包
目錄
通過遞迴組合方式展開引數包
- 組合關係也稱為複合關係,實際上就是 一種包含關係
class B { //..... }; class A { public: B b; //A中包含B物件,b作為類A的成員變數 };
通過遞迴組合方式示例
//主模板定義(泛化版本的類别範本) template <typename ...Args> class myclasst { public: myclasst() { printf("myclasst::myclasst()泛化版本執行了,this = %p\n", this); } }; //template <typename ...Args>class myclasst; //主模板宣告(前向宣告/前置宣告) template <typename First, typename ... Others> class myclasst<First, Others...> //:private myclasst<Others...> //偏特化 { public: myclasst() :m_i(0) { printf("myclasst::myclasst()偏特化版本執行了,this = %p,sizeof...(Others)=%d\n", this, sizeof...(Others)); } myclasst(First parf, Others... paro) :m_i(parf) , m_o(paro...) //, myclasst<Others...>(paro...) { cout << "---------------------begin-----------------" << endl; printf("myclasst::myclasst(parf,...paro)執行了,this = %p\n", this); cout << "m_i = " << m_i << endl; cout << "---------------------end-----------------" << endl; } First m_i; myclasst<Others...> m_o; //**************** }; template<> class myclasst<> //一個特殊的特化版本,看起來象全特化,不是全特化,可變參模板不存在全特化 { public: myclasst() { printf("myclasst::myclasst()特殊的特化版本執行了,this = %p\n", this); } };
- 呼叫
myclasst<int, float, double> myc(12, 13.5, 23);
- 輸出
- 關係圖
通過tuple和遞迴呼叫展開引數包
- tuple:元組——可變參類别範本
tuple<float, int, int> mytuple(12.5f, 100, 52); //一個tuple(元組),一堆各種型別資料的組合 //元組和列印,用標準庫中的get(函式模板) cout << get<0>(mytuple) << endl; //12.5f cout << get<1>(mytuple) << endl; //100 cout << get<2>(mytuple) << endl; //52
通過tuple和遞迴呼叫展開引數包示例
//泛化版本 template <int mycount,int mymaxcount,typename ...T> //mycount用於統計,從0開始,mymaxcount表示引數數量,可以用sizeof...取得。 class myclasst4 { public: //靜態成員函式,藉助tuple(型別),藉助get,就能夠把每個引數提取出來 static void mysfunc(const tuple<T...>& t) { cout << "value = " << get<mycount>(t) << endl; //可以把每個引數取出來並輸出 myclasst4< mycount + 1, mymaxcount, T...>::mysfunc(t); //計數每次+1,這裡是遞迴呼叫,自己呼叫自己 } }; //偏特化版本,用於結束遞迴呼叫 template <int mymaxcount, typename ...T> class myclasst4<mymaxcount, mymaxcount, T...> //注意<>中兩個都是mymaxcount { public: static void mysfunc(const tuple<T...>& t) { //這裡其實不用幹啥 } }; //可變參函式模板 template <typename ...T> void myfunctuple(const tuple<T...>& t) { myclasst4<0, sizeof...(T), T...>::mysfunc(t);//這裡注意,第一個引數是0,表示計數從寧0開始 }
- 呼叫
tuple<float, int, int> mytuple(12.5f, 100, 52); myfunctuple(mytuple);
- 輸出結果
基類引數包的展開:演示一下某個類的基類也可以是可變參
template<typename... myclassPList> class myclasst5 : public myclassPList... { public: myclasst5() : myclassPList()... { cout << "myclasst5::myclasst5,this = " << this << endl; } }; class PA1 { public: PA1() { cout << "PA1::PA1,this = " << this << endl; } private: char m_s1[100]; }; class PA2 { public: PA2() { cout << "PA2::PA2,this = " << this << endl; } private: char m_s1[200]; }; class PA3 { public: PA3() { cout << "PA3::PA3,this = " << this << endl; } private: char m_s1[300]; };
- 呼叫
myclasst5<PA1, PA2, PA3> obj; cout << "sizeof(obj)=" << sizeof(obj) << endl;
- 輸出
特化
- 可變參模板不存在全特化,所以只有偏特化
template<typename ...Args> //泛化版本 class myclasst { public: myclasst() { printf("myclasst泛化版本執行了,this=%p,sizeof...(Args)=%d\n", this, sizeof...(Args)); } }; template<typename First,typename...Others> class myclasst<First, Others...> //特化版本 { public: myclasst() { printf("myclasst<First, Others...>偏特化版本執行了,this=%p,sizeof...(Others)=%d\n", this, sizeof...(Others)); } }; template<typename Arg> class myclasst <Arg> { public: myclasst() { printf("myclasst<Arg>偏特化版本執行了,this=%p\n", this); } }; template<typename Arg1,typename Arg2> class myclasst <Arg1,Arg2> { public: myclasst() { printf("myclasst<Arg1,Arg2>偏特化版本執行了,this=%p\n", this); } };
- 呼叫
myclasst<int> myc1; myclasst<int,float> myc2; myclasst<int,float,double> myc3; myclasst<int,float,double,char> myc4; myclasst<> myc5;
- 輸出
相關文章
- C++ 可變引數模板遞迴展開C++遞迴
- 利用閉包傳遞引數
- 通過行為引數化傳遞程式碼
- c++可變模板引數C++
- c++ 模板模板引數("Template Template Parameters")C++
- C++引數的傳遞方式C++
- C++ 預設引數與引用傳遞:語法、用法及示例C++
- C#程式設計:ref【引數按引用傳遞】C#程式設計
- C++預設引數C++
- 遞迴函式,可變引數列表遞迴函式
- 函式引數傳遞及返回函式
- 引數傳遞
- vue事件帶預設引數,怎麼傳遞其他引數Vue事件
- JAVA基礎之-引數傳遞Java
- c++ -- 二維陣列引數傳遞C++陣列
- C#通過反射獲取類中的方法和引數個數,反射呼叫方法帶引數C#反射
- 現代c++模板超程式設計:遍歷tupleC++程式設計
- pygame模組引數彙總(python遊戲程式設計)GAMPython遊戲程式設計
- 引數的定義和引數的傳遞
- Mybatis引數傳遞MyBatis
- 全網最適合入門的物件導向程式設計教程:48 Python函式方法與介面-位置引數、預設引數、可變引數和關鍵字引數物件程式設計Python函式
- Python語法—函式及引數傳遞Python函式
- apicloud拉起小程式並傳遞引數APICloud
- C++ 遞迴與物件導向程式設計基礎C++遞迴物件程式設計
- 華為升級系列化產品組合方案,引領數字基礎設施發展
- 模板引數,模板分離編譯編譯
- Mybatis引數傳遞&註解開發MyBatis
- React事件傳遞引數React事件
- 路由元件傳遞引數路由元件
- Java方法04:命令列傳遞引數、可變引數Java命令列
- 檢視JVM預設引數及微調JVM啟動引數JVM
- ABAP 方法呼叫的引數傳遞裡,透過引用傳遞的方式,能修改原始引數值嗎?
- kettle通過命令列引數傳遞資料庫連線資訊命令列資料庫
- C++反射機制:可變引數模板實現C++反射C++反射
- Rust 程式設計,讀取命令列引數Rust程式設計命令列
- C++行內函數、函式過載與函式預設引數C++函數函式
- 數值型模板引數的應用
- Jmeter 跨執行緒組引數傳遞的方法JMeter執行緒