I have two C++ abstract classes Abs1
and Abs2
. Then I have:
`A : public Abs1`
`B : public Abs1`
`C : public Abs2`
`D : public Abs2`
Now, I'm trying to create objects from command line arguments and I have to do rewrite the public factory function make_abstract
in the linked question, something like:
std::unique_ptr<Abs1> makeAbs1 (int argc, const char*argv[])
{
if (argc == 1) {
return nullptr;
}
const std::string name = argv[1];
if (name == "A") {
return detail::make_abstract<A, std::tuple<int, std::string, int>>(argc, argv);
} else if (name == "B") {
return detail::make_abstract<B, std::tuple<int, int>>(argc, argv);
}
}
std::unique_ptr<Abs2> makeAbs2 (int argc, const char*argv[])
{
if (argc == 1) {
return nullptr;
}
const std::string name = argv[1];
if (name == "C") {
return detail::make_abstract<C, std::tuple<int>>(argc, argv);
} else if (name == "D") {
return detail::make_abstract<D, std::tuple<int, float>>(argc, argv);
}
}
As you can see this is terribly redundant. How can I do a generic version of this? In this version we can pass as many implemented class as we want, so the if
cascade is not a solution. Notice that we cannot modify any of these classes.
I was thinking that maybe variadic templates could help, but I can't figure out many problems:
template <typename T, typename ...Ts>
std::unique_ptr<T> make (int argc, const char*argv[]){
const std::string name = argv[1];
for(Ti : Ts) //this is obviously wrong
if(typeid(Ti).name == name)
return detail::make_abstract<T, std::tuple</*Here shoudl be different for every Ti*/>>(argc, argv);
}