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
.
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 zuB*
s in dasstd::any
Objekt und keine abgeleiteten Klassenzeiger einzufügen, ist das Problem recht einfach zu lösen.myTools
Tools sind, warum nicht einfach eineTool
Basisklasse haben undmyTools
einestd::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?Antworten:
Das ist unerreichbar. Es ist nur möglich, ein Objekt herauszuholen,
std::any
indem genau der Typ verwendet wird, der darin platziert wurde. Sie müssen also den Typ kennen, um etwas daraus zu machen.Es scheint, dass
std::any
das nicht zu Ihrem Anwendungsfall passt.quelle
Das Hinzufügen einer Basisklasse "Tool" mit einem enum ToolType-Attribut kann hilfreich sein. Dann können Sie mit dem ToolType die Besetzung festlegen.
quelle