我目前正在编写一个允许获取和设置内部程序选项的类,它应该非常灵活且易于使用。 具体而言,选项由枚举类型和值类型标识,它们具有一对一的关系。例如,枚举 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>, ...{
...
}
每个枚举常量都有一个关联的字符串表示形式,它是常量,但选项也被作为字符串输入到程序中,所以我必须能够从字符串中推导出我应该更改的选项。
但显然,此代码不能用于直接调用set或get值而不限定其完整模板特化。所以
A* a = ...
a->setValue("intoption", 5);
无效。
关于我应该使用什么来指导这项工作的任何指示?
关于如何在编译时派生OPTION1映射到int和IntType,...的部分答案也很棒。
提前致谢, Broes
答案 0 :(得分: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并可能使用他们的库。
答案 1 :(得分:0)
由于您在运行时填充数据,template
对此设计不可行。具有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