Допустим, у меня есть std::any
объект, который может содержать или не содержать указатель на некоторый производный класс данного базового класса B
. Можно ли как-нибудь сделать что-то, что:
- Возвращает
B *
, если объект std::any
содержит что-то конвертируемое в B *
, или - Бросает исключение, еслине так?
Кажется, что dynamic_cast
и std::any_cast
каждый обеспечивает половину этой функциональности, но я не вижу никакого способа соединить их вместе.
IЯ знаю, что могу выполнить эту работу различными способами, включая явное перечисление каждого типа, преобразуемого в B *
, но это является причиной всех нарушений DRY.
Пример использования:
std::vector<std::any> setupTools(const std::string & confFile)
{
std::vector<std::any> myTools;
auto conf = parse(confFile);
for(std::string & wrenchInfo : conf["Wrenches"])
{
Wrench::setup(myTools, wrenchInfo);
}
for(std::string & hammerInfo : conf["Hammers"])
{
Hammer::setup(myTools, hammerInfo);
}
// 25 more kinds of tools
}
Factory1::init(const std::vector<std::any> & tools)
{
m_wrench = any_get<Wrench *>(tools);
m_hammer = any_get<Hammer *>(tools);
m_saw = any_get<Saw *>(tools);
}
Factory2::init(const std::vector<std::any> & tools)
{
m_wrench = any_get<TorqueWrench *>(tools);
}
Factory3::init(const std::vector<std::any> & tools)
{
m_saw = any_get<CordlessReciprocatingSaw *>(tools);
}
Я не хочу включать кучу шаблонного кода, в котором перечислены все существующие типы пил, чтобы я мог взять пилу - любую Saw
- для использования в Factory1
.