C++变参模板类
C++可變參數(shù)模板
之前學習模板,都是固定參數(shù)的模板,前段時間看源碼時,注意到了變參模板類,覺得很有意思。
什么是可變參模板
template<typename... Args> class MoreApply;如上,就是一個可變參模板類的申明。至于Args…中傳進來多少參數(shù),由使用者決定。了解變參模板函數(shù)的程序員都知道,變參模板作難的是參數(shù)展開,變參模板類也不例外,接下來,介紹兩種常見的變參模板類參數(shù)展開方法:
1.包含展開
下面代碼展示了一個變參模板類,遍歷所有模板參數(shù),判斷一個值。
#include<iostream> using namespace std;//純虛函數(shù) struct AbstractBase {virtual bool hander(const int& n) = 0; };//變參模板類的申明 template <typename... Args> struct VarParaClass;//變參模板類的展開,這里我們把參數(shù)分成兩塊,第一塊參數(shù)T,和第二塊參數(shù)Args...; //T和VarParaClass<Args...>分別作為VarParaClass<T, Args... >類的成員變量 //VarParaClass<T, Args... >中的hander函數(shù)首先調(diào)用T中的hander函數(shù),然后得到一個狀態(tài)status,根據(jù)這個狀態(tài)判斷是否要調(diào)用下一個參數(shù)包 template<typename T, typename ... Args> struct VarParaClass<T, Args... > : AbstractBase {virtual bool hander(const int& n){auto& first = static_cast<AbstractBase&>(t);bool status = first.hander(n);if(status)return status;auto& next = static_cast<AbstractBase&>(args);return next.hander(n);} private:T t;VarParaClass<Args...> args; };// 模板特化,終止展開參數(shù)包的條件 template<> struct VarParaClass<>:AbstractBase {virtual bool hander(const int& n){std::cout << "nothing" << std::endl;return false;} };// 參數(shù)包,每個參數(shù)包都繼承了AbstractBase,并且復寫了hander方法 struct ParaClass1 : AbstractBase {bool hander(const int& n){if( n == 1){std::cout << "ParaClass1" << std::endl;return true;}else{std::cout << "next hander2" << std::endl;return false;}} };struct ParaClass2 : AbstractBase {bool hander(const int& n){if( n == 2){std::cout << "ParaClass2" << std::endl;return true;}else{std::cout << "next hander3" << std::endl;return false;}} };struct ParaClass3 : AbstractBase {bool hander(const int& n){if( n == 3){std::cout << "ParaClass3" << std::endl;return true;}else{std::cout << "last hander" << std::endl;return false;}} };int main() {VarParaClass<ParaClass1,ParaClass2,ParaClass3> A;AbstractBase* p = &A;p->hander(2);return 0; }**注意:**充分利用多態(tài),因為所有的類都繼承了抽象類AbstractBase;
變參模板類的申明和終止模板必須有。
下面展示一些 輸出。
// An highlighted block next hander2 ParaClass22.繼承展開
//純虛函數(shù) struct AbstractBase {virtual bool hander(const int& n) = 0; };//變參模板類的申明 template <typename... Args> struct VarParaClass;//變參模板類的展開,這里我們把參數(shù)分成兩塊,第一塊參數(shù)T,和第二塊參數(shù)Args...; //T和VarParaClass<Args...>分別繼承到VarParaClass<T, Args... >類下 //VarParaClass<T, Args... >中的hander函數(shù)首先調(diào)用T中的hander函數(shù),然后得到一個狀態(tài)status,根據(jù)這個狀態(tài)判斷是否要調(diào)用下一個參數(shù)包 template<typename T, typename ... Args> struct VarParaClass<T, Args... > : T, VarParaClass<Args...> {bool hander(const int& n){bool status = T::hander(n);if(status == false)return VarParaClass<Args...>::hander(n);return status;} };// 模板特化,終止展開參數(shù)包的條件 template<> struct VarParaClass<>: AbstractBase {bool hander(const int& n){std::cout << "nothing" << std::endl;return false;} };struct ParaClass1 : AbstractBase {bool hander(const int& n){if( n == 1){std::cout << "ParaClass1" << std::endl;return true;}else{std::cout << "next hander2" << std::endl;return false;}} };struct ParaClass2 : AbstractBase {bool hander(const int& n){if( n == 2){std::cout << "ParaClass2" << std::endl;return true;}else{std::cout << "next hander3" << std::endl;return false;}} };struct ParaClass3 : AbstractBase {bool hander(const int& n){if( n == 3){std::cout << "ParaClass3" << std::endl;return true;}else{std::cout << "last hander" << std::endl;return false;}} };int main() {VarParaClass<ParaClass1,ParaClass2,ParaClass3> A;A.hander(4);return 0; } \\輸出 next hander2 next hander3 last hander nothing總結(jié)
可以看出,變參模板類的使用給變成帶來了很多便利,但是使用起來并沒有那么簡單,變參模板類的使用需要設(shè)計,不管是使用包含展開還是繼承展開,都需要程序員自己去設(shè)計,并沒有一個簡單的模板套用。
變參函數(shù)學習,可以參考如下鏈接
鏈接: link
總結(jié)
- 上一篇: 工程材料学习3——第二章 金属材料组织和
- 下一篇: C++ 模板类与头文件