Angenommen, ich habe ein std::any
Objekt, das möglicherweise einen Zeiger auf eine abgeleitete Klasse einer bestimmten Basisklasse enthält oder nicht B
. Kann ich auf irgendeine Weise etwas tun, das:
- Gibt a zurück
B *
, wenn dasstd::any
Objekt etwas enthält, das inB *
oder konvertierbar ist - Wirft eine Ausnahme, wenn nicht?
Es scheint so , dynamic_cast
und stellen std::any_cast
jeweils eine Hälfte dieser Funktionalität, aber ich sehe keine Möglichkeit , die beiden zusammen zu stellen.
Ich bin mir bewusst, dass ich diese Arbeit auf verschiedene Arten machen kann, bei denen jeder konvertierbare Typ explizit aufgelistet wird B *
, aber das ist die Mutter aller DRY-Verstöße.
Anwendungsbeispiel:
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);
}
Ich möchte keinen Haufen Boilerplate-Code einfügen, der jede existierende Säge auflistet, nur damit ich mir eine Säge schnappen kann - jede Saw
-, in der ich sie verwenden kann Factory1
.
B*
s in das std::any
Objekt und keine abgeleiteten Klassenzeiger einzufügen, ist das Problem recht einfach zu lösen.
myTools
Tools sind, warum nicht einfach eine Tool
Basisklasse haben und myTools
eine std::vector<std::unique_ptr<Tool>>
erstellen?
myTools
existiert; Warum möchten Sie das, was Sie für völlig unterschiedliche Objekte halten, in das Objekt einfügen und es dann wiederholen, um sich daran zu erinnern, was Sie dort abgelegt haben?
std::any
dies verwenden müssen und was Sie insgesamt zu lösen versuchen? Das klingt nach einem sehr unangenehmen Problem und es gibt wahrscheinlich einen besseren Weg, es zu