Reputation: 850
Is there any way to use a parameter pack to create an initializer list of objects or to insert objects into a std::vector
? The problem I am having is all examples of parameter packs I have seen use passed arguments for the compiler to be able to differentiate which function it needs to call. The thing is that I have no arguments to pass to the functions just the types.
Example:
// compiler cannot determine which function is correct
namespace impl
{
template<class T, class... U>
void get_type_impl(std::vector<MetaClass*>& types)
{
// rusty::get<T>(); just retrieves a MetaClass object for the specified type
types.emplace_back(rusty::get_type<T>());
impl::get_type_impl<U...>(types);
}
template <class T>
void get_type_impl(std::vector<MetaClass*>& types)
{
types.emplace_back(rusty::get_type<T>());
}
}
template <class... T>
std::vector<MetaClass*> get_types()
{
std::vector<MetaClass*> types;
types.reserve(sizeof...(T));
impl::get_type_impl<T...>(types);
return types;
}
Example Usage:
auto types = get_types<MovementComponent, GraphicsComponent>();
Edit:
The goal is to create a vector of objects that are created from the provided template types. The current problem I have is that the compiler cannot deduce which function to use. As both get_type_impl
can have the same function signature.
Solution:
namespace impl
{
template <class T>
void get_type_impl(std::vector<MetaClass*>& types)
{
types.emplace_back(rusty::get_type<T>());
}
template<class T0, class T1, class... Tn>
void get_type_impl(std::vector<MetaClass*>& types)
{
types.emplace_back(rusty::get_type<T0>());
impl::get_type_impl<T1, Tn...>(types);
}
}
template <class... T>
std::vector<MetaClass*> get_types()
{
std::vector<MetaClass*> types;
types.reserve(sizeof...(T));
impl::get_type_impl<T...>(types);
return types;
}
The solution is to force one of the get_type_impl
to take at least 2 template types and the other to simply take 1. This creates enough a difference in the signatures for the compiler to determine which is the correct function.
Upvotes: 1
Views: 859
Reputation: 66200
Not sure to understand but... it seems to me that you'r looking for something as follows (caution: code not tested):
template <typename ... Ts>
std::vector<MetaClass*> get_types()
{ return { rusty::get_type<Ts>()... }; }
Otherwise, to solve the problem with get_types_impl()
, I suggest to delete the second function
template <class T>
void get_type_impl(std::vector<MetaClass*>& types)
{
types.emplace_back(rusty::get_type<T>());
}
and substitute it with the following ground case
template <int = 0>
void get_type_impl (std::vector<MetaClass*> const &)
{ }
The idea behind this is add (emplace_back()
) elements in types
through the first version of get_types_impl()
and make so the last call, when the variadic type list U...
is empty and is called
impl::get_type_impl<>(types);
, is hijacked (thanks the default not type template parameter int=0
) to the ground case.
Upvotes: 3