[英]C++ template specify type by Enum
我面臨一個問題:我想創建一個函數,該函數根據函數將接收的枚舉來調用特定的模板類型構造函數。 我的意思是:
typedef ____ (Class<whatever>::*tabType)(int flag);
template<typename T>
static Class* Class<t>::createClassInstance(enum precision)
{
static const ___ createTab[] = {
Class<int>,
Class<double>
}
return (new createTab[precision](1));
}
有很多方法可以實現這種目的,但是聽起來您想創建一個由enum
變量索引的工廠方法的數組(或映射)(每個類一個)。 每個調用相關的構造函數,並返回該類型的新對象。
當然,要使之有意義,所有類都必須派生自一個共同的基礎。
如果枚舉值作為函數參數是動態的,則必須使用調度表或switch / if-else。 請注意,您的偽代碼並未明確說明要求。 假設您要定義的createInstance函數到底是什么,將如何調用它?
我會說,只需構造一個將enum
映射到工廠函數的std::map
( boost::function<>
)。 然后,您只需為每種類型添加一個條目,並帶有相應的enum
。 實際構造工廠功能。 您可以為每個類都具有一些static Create()
函數並存儲一個函數指針。 或者,您可以使用Boost.Lambda 構造函數/析構函數函子。 或者,您可以使用Boost.Bind構造函子,該函子包裝需要一些參數的工廠函數。 這是一個例子:
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/lambda/construct.hpp>
#include <map>
struct Base { };
struct Derived1 : public Base { };
struct Derived2 : public Base {
static Base* Create() { return new Derived2; };
};
struct Derived3 : public Base {
int value;
Derived3(int aValue) : value(aValue) { };
static Base* Create(int aValue) { return new Derived3(aValue); };
};
enum DerivedCreate { ClassDerived1, ClassDerived2, ClassDerived3 };
int main() {
std::map< DerivedCreate, boost::function< Base*() > constructor_map;
constructor_map[ClassDerived1] = boost::lambda::new_ptr<Derived1>();
constructor_map[ClassDerived2] = &Derived2::Create;
constructor_map[ClassDerived3] = boost::bind(&Derived3::Create, 42);
//now you can call any constructor as so:
Base* ptr = constructor_map[ClassDerived2]();
};
我可能在語法上犯了一些小錯誤,但是基本上您應該可以完成上述工作。 同樣,您擁有多個類模板的事實也沒有作用,一旦將它們實例化為具體的類(例如Class<int>
或Class<double>
),它們便與其他任何類一樣,並且上述想法應保持有效。
擴展您的示例,類似以下內容的工作:
enum Prec {INT, DOUBLE};
struct Base
{
virtual ~Base () = 0 {}
};
template<typename T> struct Class : public Base
{
static Base* create (int flag) {return new Class<T> (flag);}
Class (int flag) {}
};
typedef Base* (*Creator) (int flag);
Base* createClassInstance (Prec prec)
{
static const Creator createTab[] = {
Class<int>::create,
Class<double>::create
};
return createTab[prec] (1);
}
int main (int argc, char* argv[])
{
Base* c = createClassInstance (DOUBLE);
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.