Digamos que tengo un std::any
objeto que puede o no contener un puntero a alguna clase derivada de una clase base dada B
. ¿Hay alguna manera de hacer algo que:
- Devuelve a
B *
, si elstd::any
objeto contiene algo convertible aB *
, o - ¿Lanza una excepción si no?
Parece que dynamic_cast
y std::any_cast
cada una proporciona la mitad de esta funcionalidad, pero no veo ninguna manera de poner los dos juntos.
Soy consciente de que puedo hacer que esto funcione de varias maneras que implican enumerar explícitamente cada tipo de convertible a B *
, pero esa es la madre de todas las violaciones DRY.
Caso de uso de muestra:
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);
}
No quiero incluir un montón de código repetitivo que enumere cada tipo de sierra existente solo para poder agarrar una sierra, cualquiera Saw
, para usar Factory1
.
B*
s en el std::any
objeto, y no punteros de clase derivados, eso resuelve el problema con bastante facilidad.
myTools
son herramientas, ¿por qué no simplemente tener una Tool
clase base y hacer myTools
una std::vector<std::unique_ptr<Tool>>
?
myTools
existe; ¿por qué quieres poner lo que afirmas que son objetos completamente diferentes en él, luego iterar sobre ellos para tratar de recordar lo que pusiste allí?
std::any
esto y qué está tratando de resolver en general? Esto suena como un problema muy incómodo y probablemente haya una mejor forma de