Digamos que eu tenho um std::any
objeto que pode ou não conter um ponteiro para alguma classe derivada de uma determinada classe base B
. Existe alguma maneira de fazer algo que:
- Retorna a
B *
, se ostd::any
objeto mantiver algo convertível emB *
, ou - Lança uma exceção, se não?
Parece que dynamic_cast
e std::any_cast
cada fornecer metade desta funcionalidade, mas eu não vejo nenhuma maneira de colocar os dois juntos.
Estou ciente de que posso fazer isso funcionar de várias maneiras que envolvam enumerar explicitamente todos os tipos conversíveis B *
, mas essa é a mãe de todas as violações DRY.
Exemplo de caso de uso:
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);
}
Não quero incluir um monte de código padrão listando todos os tipos de serra existentes, para que eu possa pegar uma serra - qualquer Saw
- para usar Factory1
.
B*
s no std::any
objeto, e não em indicadores de classe derivados, isso resolve o problema com bastante facilidade.
myTools
são ferramentas, por que não apenas ter uma Tool
classe base e criar myTools
uma std::vector<std::unique_ptr<Tool>>
?
myTools
existe; por que você deseja colocar o que afirma ser objetos totalmente diferentes? iterar sobre eles para tentar se lembrar do que você colocou lá?
std::any
isso e o que você está tentando resolver em geral? Isso soa como um problema muito estranho e provavelmente há uma melhor maneira de contornar isso