J'ai deux classes abstraites C++ Abs1
et Abs2
. Puis-je:Création d'objet générique à partir de la ligne de commande
`A : public Abs1`
`B : public Abs1`
`C : public Abs2`
`D : public Abs2`
Maintenant, je suis en train de create objects from command line arguments et je dois faire réécrire la fonction d'usine publique make_abstract
dans la question liée, quelque chose comme:
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);
}
}
Comme vous pouvez le voir est terriblement redondant. Comment puis-je faire une version générique de ceci? Dans cette version, nous pouvons passer autant de classes implémentées que nous le voulons, donc la cascade if
n'est pas une solution. Notez que nous ne pouvons pas modifier l'une de ces classes.
Je pensais que peut-être modèles variadique pourrait aider, mais je ne peux pas comprendre de nombreux problèmes:
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);
}
Vous ne pouvez pas entasser les types non apparentés dans un type de retour. À quoi ressemblerait-il sur le site d'appel? Soit il doit y avoir une classe de base partagée, ou une union (ou std :: any, etc) pour rendre utilisable – Caleth