当两个模板的类型相关联时,如何使用策略模板

How to use policy-templates if the types of two templates are linked?

本文关键字:关联 策略 何使用 两个 类型      更新时间:2023-10-16

我目前正在编写一个类,它允许获取和设置内部程序选项,它应该是相当灵活和易于使用。具体来说,一个选项由枚举类型和值类型标识,它们具有一对一的关系。例如,enum 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的部分答案,…也很好。

提前感谢,兄弟

不需要同时传递Enum 的类型。您可以通过trait类从类型本身推断枚举值:

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);
}

另外,您可能有兴趣查找Boost如何做到这一点,并可能使用他们的库。

由于是在运行时填充数据,因此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