Reputation: 85
class Base
{
public:
virtual void foo() = 0;
};
class A : public Base
{
public:
void foo() override { std::cout << "A\n"; }
};
class B : public Base
{
public:
void foo() override { std::cout << "B\n"; }
};
class Registry
{
public:
static Registry& instance()
{
static Registry s_instance;
return s_instance;
}
void register_foo(Base* foo)
{
m_vec.emplace_back(foo);
}
private:
std::vector<Base*> m_vec;
};
template<typename ... T>
class Foo : public T...
{
public:
Foo()
{
Registry::instance().register_foo(this);
}
void test() { (T::foo(), ...); }
};
int main()
{
auto f1 = std::make_unique<Foo<A, B>>();
auto f2 = std::make_unique<Foo<A>>();
f1->test();
f2->test();
}
As you can see I have a Base
class, class A
and class B
.
A
and B
inherit from Base
.
Class Foo
is a template class, which is with a variadic template.
The idea is to be able to pass class A
and class B
into Foo
.
Then this Foo
is registered in the Registry
class / pushed into a vector.
The problem is the following - as you can see I can have both Foo<A>
and Foo<A, B>
, or Foo<B, A>
.
How can I have such a vector which can accept all possible types of Foo
?
Upvotes: 0
Views: 280
Reputation:
How about a simple common base class?
class FooBase {
public:
virtual ~FooBase() {}
virtual void test() = 0;
};
template<typename... T>
class Foo : public FooBase, public T...
{
public:
Foo() { }
void test() override { (T::foo(), ...); }
};
int main()
{
auto f1 = std::make_unique<Foo<A, B>>();
auto f2 = std::make_unique<Foo<A>>();
std::vector<std::unique_ptr<FooBase>> foos;
foos.push_back(std::move(f1));
foos.push_back(std::move(f2));
}
Upvotes: 1
Reputation: 31457
A std::vector
holds one type of objects. You cannot put objects of different types into the same vector (and objects created from a template with different template arguments are different types).
One option (I'd not recommend it) is having a vector that holds instances of std::any
) - works, but cumbersome and inefficient to work with. Another option is a vector of pointers to a common base class and taking advantage of polymorphism. A third option is simply having sepperate vectors for each type of object.
Upvotes: 0