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
.
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 deB*
s en elstd::any
objeto, y no punteros de clase derivados, eso resuelve el problema con bastante facilidad.myTools
son herramientas, ¿por qué no simplemente tener unaTool
clase base y hacermyTools
unastd::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í?Respuestas:
Esto es inalcanzable. Solo es posible sacar un objeto
std::any
usando exactamente el tipo que se puso dentro. Por lo tanto, debe conocer el tipo para sacar algo de él.Parece que
std::any
no se ajusta a su caso de uso.fuente
Agregar una clase base "Herramienta" que tenga un atributo enum ToolType puede ayudar. Luego, utilizando ToolType, puede decidir sobre el reparto.
fuente