Как использовать шаблоны политики, если типы двух шаблонов связаны между собой? - PullRequest
1 голос
/ 05 октября 2011

В настоящее время я пишу класс, который позволяет получать и устанавливать параметры внутренней программы, и он должен быть достаточно гибким и простым в использовании. В частности, опция идентифицируется типом перечисления и типом значения, которые имеют отношение один к одному. Например, 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 или получения значений без определения его полной специализации шаблона. Так

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

не будет работать.

Какие-нибудь указатели на то, что я должен использовать, чтобы заставить это работать?

Частичный ответ о том, как получить во время компиляции, что OPTION1 отображается на int и IntType, ... также был бы хорош.

Спасибо заранее, Broes

Ответы [ 2 ]

2 голосов
/ 05 октября 2011

Нет необходимости передавать оба типа Enum и .Вы можете вывести значение 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);
}

Также,вам может быть интересно посмотреть Как это делает Boost и, возможно, использовать их библиотеку.

0 голосов
/ 05 октября 2011

Поскольку вы заполняете данные во время выполнения, 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...