Каждый экземпляр класса шаблона представляет собой отдельный тип.Следовательно, контейнеры типа std::vector
не могут содержать Prob<ProbNum>
для различных значений ProbNum
.Если вы знаете во время компиляции нужное количество Prob<ProbNum>
экземпляров и соответствующие значения параметра шаблона int ProbNum
, вы можете сохранить все в tuple
.Например:
auto mycollection = std::make_tuple(Prob<1>(), Prob<2>());
Более общим решением может быть определение абстрактного базового класса для Prob
.Тогда вам удастся сохранить вектор объектов Prob<ProbNum>
с неоднородными значениями int ProbNum
, если вы определите вектор указателей на базовый класс.Чтобы это работало, вы должны предоставить интерфейс в базовом классе, т. Е. Каждый член Prob<ProbNum>
, к которому вы хотите получить доступ через vector
базового класса, должен быть virtual
и уже объявлен в базовом классе.
Рассмотрим следующий пример:
#include <iostream>
#include <memory>
#include <vector>
struct base {
virtual void print() const = 0;
virtual ~base() = default;
};
template <int i>
struct derived : public base
{
virtual void print() const { std::cout << i << std::endl; }
};
int main()
{
std::vector<std::unique_ptr<base>> vec;
vec.emplace_back(new derived<1>());
vec.emplace_back(new derived<3>());
vec.emplace_back(new derived<5>());
for (auto& el : vec)
el->print();
return 0;
}
Переменная vec
по сути является вектором указателей на объекты типа derived<i>
с неоднородными значениями i
.Поскольку base::print()
является виртуальным, он правильно разрешается в соответствующий метод класса derived<i>
.Обратите внимание, что я использовал умный указатель , чтобы избежать утечки памяти.
Также важно объявить virtual
деструктором base
, см. Обсуждение Почему я долженобъявить виртуальный деструктор для абстрактного класса в C ++? .