У меня есть два абстрактных класса C++ Abs1
и Abs2
. Тогда у меня есть:Создание общего объекта из командной строки
`A : public Abs1`
`B : public Abs1`
`C : public Abs2`
`D : public Abs2`
Теперь я пытаюсь create objects from command line arguments, и я должен сделать переписать функцию общественной заводской make_abstract
в связанном вопросе, что-то вроде:
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);
}
}
Как вы можете видеть это ужасно избыточно. Как я могу сделать общий вариант этого? В этой версии мы можем передать столько реализованного класса, сколько хотим, поэтому каскад if
не является решением. Обратите внимание, что мы не можем изменить какой-либо из этих классов.
Я думал, что, может быть, VARIADIC шаблоны могли бы помочь, но я не могу понять, много проблем:
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);
}
Вы не можете просто впихнуть несвязанных типов в тип возвращаемого значения. Как бы это выглядело на сайте вызова? Либо должен быть общий базовый класс, либо союз (или std :: any и т. Д.), Чтобы сделать его пригодным для использования. – Caleth