Обработка универсального параметра с проверкой типа - PullRequest
0 голосов
/ 31 мая 2019

В настоящее время я пытаюсь реализовать проверку типов по универсальному параметру, и я понятия не имею, возможно ли это как-то без перегрузки функций и методов, возможности, которую я хотел бы избежать. Я постараюсь объяснить, что я пытаюсь сделать ниже.

У меня есть класс Algorithm, который используется в качестве базы для описания нескольких алгоритмов. Каждый из них может иметь свои конкретные параметры в качестве входа и выхода. Я мог бы перегрузить основной метод Run, но мне пришлось бы делать это для любого нужного мне типа, который может быстро стать длинным списком. Поэтому я решил попробовать сделать что-то вроде этого:

class Algorithm {
public:
  Algorithm();

  GenericParameter* Run(GenericParameter* input);
};

class Alg0 : public Algorithm { ... };
class Alg1 : public Algorithm { ... };
class Alg2 : public Algorithm { ... };

GenericParameter является специализированным типом и основан на двух основных классах, шаблонном TParam классе, который не может быть изменен. Идея в том, что каждая специализация TParam наследует класс GenericParameter:

template <typename T>
class TParam {
public:
  TParam() {
    throw std::runtime_error("Cannot instanciate this object");
  }
  TParam(const T& elmt) {
    throw std::runtime_error("Cannot instanciate this object");
  }
};

class GenericParameter {
protected:
  GenericParameter();
  virtual ~GenericParameter();

  // To create a TParam<T> instance. 
  // Will fail if no specialization.
  template <typename T>
  static GenericParameter* Create(const T& elmt) {
    return new TParam<T>(elmt);
  }
  // To create a TParam<T> instance. 
  // Will fail if no specialization
  template <typename T>
  static GenericParameter* Create() {
    return new TParam<T>();
  }
  // To get the object in the TParam<T> param
  template <typename T>
  static T& Get(GenericParameter* param) {
    TParam<T>* tmp = static_cast<TParam<T>* >(param);
    return tmp->object;
  }
};

template <>
class TParam<TypeA> : public GenericParameter {
public:
  TParam<TypeA>() {};
  TParam<TypeA>(const TypeA& elmt): object(elmt) {};
  TypeA object;
};

template <>
class TParam<TypeB> : public GenericParameter {
public:
  TParam<TypeB>() {};
  TParam<TypeB>(const TypeB& elmt): object(elmt) {};
  TypeB object;
};

Используя статические методы Create и Get, я могу легко создавать любые параметры, предположив, что я специализировал связанный класс TParam.

Я использовал его, он работает, предполагая, что вы знаете, какой тип у вас есть в качестве входных данных, и вы должны вернуться в Algorithm унаследованных классах. Но одна вещь беспокоит меня в том факте, что приведенный ниже код компилируется и запускается:

TypeA aobj();
GenericParameter* aobj_p = GenericParameter::Create(aobj);
TypeB bobj = GenericParameter::Get<TypeB>(aobj_p);

Поскольку я не проверяю тип, я могу получить объект TypeB из экземпляра GenericParameter, пока он оборачивает объект TypeA. Я пробовал решение для проверки типов, основанное на перечислении и поле типа в классе GenericParameter, но я хотел бы знать, видит ли кто-нибудь другую возможность для этого.

Я могу обеспечить реализацию методов, если кто-то захочет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...