Разработка hiearchical классов с функцией шаблона - PullRequest
0 голосов
/ 04 октября 2011

Я пишу класс Base, в котором есть функция-член, принимающая параметр шаблона:

class Base {
  template<class T>
  void func(const T& t) { ... }
};

Существует класс Derived, который концептуально наследует природные значения Base и имеет ту же функцию func с различной реализацией.

Сначала я подумал о том, чтобы извлечь Derived из Base и сделать func виртуальным, но я не могу, потому что это шаблон.

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

std::vector<Base*> v = ...;
v[0]->func(...);
v[1]->func(...);

Перегрузка для возможных типов T также не возможна.

Как лучше всего решить эту ситуацию?

И помимо темы, вы бы порекомендовали ссылки (желательно книги) для такого рода проблем?

Ответы [ 2 ]

1 голос
/ 04 октября 2011

Это не легко сделать с C ++. Это связано с тем, что называется «полиморфизмом первого класса», что означает, что было бы легко, если бы значения в C ++ могли иметь полиморфные типы. Это не тот случай.

Если вам подходит стандартное решение (это означает, что код f должен быть одинаковым для всех T), вы можете сделать это, но это будет трудоемкая задача.

По сути, вы захотите заменить параметр const T &t параметром, тип которого не будет универсальным, но будет захватывать "внутри" все поведение, необходимое f из t s всех возможных типов. .

Для примера, скажем, T должен быть функтором, который f вызывает с аргументом int. В этом случае вы измените объявление на

  virtual void func(const std::function<void(int)>& t) { ... }

и виртуальные функции начнут работать. Однако это означает, что интерфейс T s должен быть исправлен до того, как вы начнете реализовывать его в производных классах (то есть, если вы передумаете и захотите вызвать t с аргументом типа ostream, вы ' не повезло).

Однако создание таких полиморфных оболочек варьируется от простых (как boost::any, boost::function) до сложных или даже невозможных (any_iterator ). Это очень зависит от того, что вы хотите сделать.

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

Нельзя смешивать полиморфизм времени компиляции (шаблоны) с таким полиморфизмом времени исполнения.Проблема в том, что с шаблоном компилятор будет генерировать код по требованию при его использовании, и в вашем конкретном случае вы хотите решить, какую функцию-член создавать, основываясь на типе времени выполненияобъект в векторе.

Если число типов, которые можно использовать с методами, ограничено, вы можете предоставить различные виртуальные перегрузки, если вы не хотите делать это вручную, вы, вероятно, можете определить типсписок со всеми типами T, а затем использовать этот список типов для генерации методов ... но это будет ужасно для кода и обслуживания.

Я рекомендую вам указать фактические требования проблемы (а нетребования вашего предложенного решения), и люди смогут предоставить альтернативные подходы.

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