2011-10-05 119 views
1

我目前正在寫的一類,它允許獲取和設置INTERAL程序選項,它應該是相當靈活,易於使用。 具體而言,一個選項由枚舉類型和值類型標識,它們具有一對一的關係。例如,枚舉IntType上意願包含具有INT類型的選項。如果兩個模板的類型鏈接,如何使用策略模板?

我心目中的下面的代碼,但不知道如何得到它的工作或我是否想在某種程度上我不應該使用的模板。

enum IntType {OPTION1, OPTION2} 
enum StringType { OPTION3, OPTION4} 

template<class T, class T2> 
class Policy{ 
public: 
    T2 getValue(const T& a); 
    void setValue(const std::string& name, const T2& a); 
    ... 
} 

class A: public Policy<IntType, int>, public Policy<Stringtype, std::string>, ...{ 
    ... 
} 

每個枚舉常數具有一個相關聯的字符串表示,這是不變的,但選擇也作爲字符串輸入到程序中,所以必須要能夠從我應該改變哪個選項的字符串來推斷。

但顯然,不能用此代碼來直接調用設置或獲取價值,而不必限定其全模板特殊化。所以

A* a = ... 
a->setValue("intoption", 5); 

將無法​​正常工作。

上我應該用什麼來得到這個工作的任何指針?

關於如何在編譯時派生出OPTION1映射到int和IntType的部分答案,也會很棒。

由於提前, Broes

+0

你的第一個模板參數是你的枚舉嗎?爲什麼不簡單通過價值傳遞呢? – Geoffroy

+0

我更新了問題,因爲枚舉規範不夠清楚。 –

+0

好吧,現在我明白你的意思了;) – Geoffroy

回答

2

這是沒有必要通過兩個Enum類型。你可以從類型本身中推導出枚舉值,這要歸功於一個特徵類:

template <typename T> 
struct PolicyTraits; 

template <> 
struct PolicyTraits<int> { static Enum const value = IntType; } 

// ... and so on ... 

你的選擇顯然有點困難。要使模板正常工作,您需要基於編譯常量選擇,無論它們是常量還是類型。這要求你的選項名稱是常量。因此

修訂的實施將是:

template<class Name, class Type> 
class Policy{ 
public: 
    Type getValue(Name); 
    void setValue(Name, Type const&); 
    ... 
} 

這可以作爲:

struct IntOption {}; 

class A: public Policy<IntOption, int> {}; 

int main() { 
    A a; 
    a.setValue(IntOption(), 3); 
} 

此外,您可能會感興趣的仰視How Boost does it也許使用他們的圖書館。

+0

這不是我想到的,但是有了你的信息和「現代C++設計」的一些幫助,我找到了答案。主要觀點是創建一個具有嵌入式typedef的traits類用於我的類型。 –

0

既然你是填充在運行時的數據,template s爲不可行的這種設計。運行時多態性與virtual函數將是一個不錯的選擇。例如,現在

class Options; // Say this is the class of interest 

class DataType { 
public: 
    virtual Options& getOptions() = 0; 
}; 

class IntType : public DataType { 
public: 
    Options& getOptions(); // implement for 'int' type 
}; 

class StringType : public DataType { 
public: 
    Options& getOptions(); // implement for 'std::string' type 
}; 

class A應包含一個指向DataType;

class A { 
    DataType *pData; 
public: 
    void setValue (DataType *p) { pData = p; } 
... 
}; 

用法:

A *a = ...; 
a->setValue(new IntType); // take care of heap allocation/stack allocation 
相關問題