Использование шаблонного класса в контейнерах STL - PullRequest
0 голосов
/ 30 октября 2018

Если у меня есть шаблонный класс, который я хочу создать с различными типами данных:

template <typename T>
class A {
  T value;
  // ...
};

И я также хочу использовать объекты этого класса в контейнере стандартной библиотеки шаблонов (скажем, vector).

В моем понимании создание вектора A объектов не будет принято компилятором, потому что A<int> и A<char> на самом деле разные типы, и я не могу поместить их в один и тот же вектор.

Обходной путь, который я нашел, - это создание базового класса, производного шаблонного класса и вектора указателей базового класса.

class ABase {
  // ...
};

template <typename T>
class ADerived : public ABase{
  T value;
  // ...
};

std::vector<BaseA*> mySuperVector;

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

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Необходимость приведения типа к производному типу не связана с тем, что производный тип является экземпляром шаблона класса, это проблема проектирования. Возможно, вам нужны виртуальные функции или несколько контейнеров.

В противном случае ваше решение в порядке, но переключитесь на std::unique_ptr, если предполагается, что контейнер владеет содержащимися объектами.

0 голосов
/ 30 октября 2018

Шаблоны - это конструкция для генерации кода во время компиляции. Если вам нужен гетерогенный контейнер объектов во время компиляции, тогда вы можете использовать std::tuple:

std::tuple my_tuple{A<int>{}, A<char>{}, A<double>{}};

Если вам нужен гетерогенный контейнер объектов во время выполнения, вам нужен какой-то полиморфизм. Использование базового класса с virtual методами является допустимым вариантом. Если вы знаете все возможные варианты выбора вашего объекта заранее, вы также можете использовать std::variant:

using my_a = std::variant<A<int>, A<char>, A<double>>;
std::vector<my_a> vec;

В этом случае my_a может быть либо A<int>, A<char>, либо A<double> в любой момент времени. Активная альтернатива может измениться во время выполнения.

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