template<class...Ts>
struct types { using type=types; };
dies ist ein Bündel von Typen.
template<class T>struct tag_t{constexpr tag_t(){}; using type=T;};
template<class T>constexpr tag_t<T> tag{};
Dies ist ein Typ-Tag.
template<class T, class U>
T* tag_dynamic_cast(tag_t<T>, U* u) {
return dynamic_cast<T*>(u);
}
template<class T, class U>
T& tag_dynamic_cast(tag_t<T>, U& u) {
return dynamic_cast<T&>(u);
}
Damit können Sie einen dynamischen Cast basierend auf einem Tag versenden.
template<class F, class Sig>
struct invoker;
template<class F, class R, class...Args>
struct invoker<F, R(Args...)> {
R(*)(void*, Args...) operator()() const {
return [](void* ptr, Args...args)->R {
return (*static_cast<F*>(ptr))(std::forward<Args>(args)...);
};
}
};
template<class F, class...Sigs>
std::tuple<Sigs*...> invokers() {
return std::make_tuple(invoker<F, Sigs>{}()...);
}
so an diesem Punkt haben wir ein Tupel von Zeigern auf Funktionen, die ein bestimmtes Objekt F
Typ mit einem Satz von Signaturen Sigs
für jede Unterschrift aufrufen wird.
Wir würden nächster einen dipatcher schreiben, die die „richtigen“ Sigs
von Sigs...
basierend auf einigen Anruf, um es auf eine std::tuple
von Sigs*
mit einem void*
ersten Argumente wählen würden.
Jetzt nehmen wir eine types<...>
der Typen, die Sie zu Cast-to unterstützen möchten. Wir verwenden das, um eine Typ-Lösch-Klasse zu erzeugen, die einen übergebenen Lambda in einem std::unique_ptr<void, void(*)(void*)>
speichert. Die Signaturen, die wir unterstützen, sind tag_t<x>
, wobei x
über die Typen in types<x...>
variiert.
Dies ist Ihr dynamischer Dispatcher.
Wir sind fast den ganzen Weg dorthin. Als nächstes bauen wir etwas, das einen dynamischen Dispatcher und einen void*
nimmt, und ruft es mit tag_t<x>
auf. Es löscht die tag_t<x>
es wird den dynamischen Dispatcher mit aufrufen, so dass die Schnittstelle es nicht verfügbar macht. Es ist im Grunde ein Binder zu einer Std-Funktion an diesem Punkt, einfach.
//STATEMENT A:
std::map<std::string , helper<derFooA, derFooB>> myMap=
{{"derfooA",tag<derfooA>}, {"derfooB", tag<derfooB>}};
myMap[str]([&](auto&& tag) {
auto* dfoo = tag_dynamic_cast(tag, baseFoo_ptr);
});
und während das Lambda wird für jeden abgeleiteten Typ, der nur eine instantiiert werden, die Lauf ist derjenige sein wird, in der Karte gespeicherten Wert übereinstimmt.
Sie werden feststellen, dass Sie innerhalb des Lambda gefangen sind. Ja. Sie können auch keine echten Informationen ausgeben, außer als Laufzeitstatus.
Jetzt sind Chancen Ihr wirkliches Problem hat eine einfachere Lösung. Aber das ist ein Fahrplan, wie es geht. Ich würde zu viel Zeit brauchen, um es selbst zu schreiben.
Die 'derFooA' in der' dynamic_cast' Anweisung weist darauf hin, dass Sie den Zieltyp kennen, warum also in einer Karte nachschlagen? – aschepler
Welches Problem versuchen Sie zu lösen? Warum brauchst du den Downcast? – Barry
Ich versuche, zu einem bestimmten Typ zu werfen, würde dieser Typ aus einer Zeichenfolge ermittelt werden. Um dies zu erreichen, würde ich liek eine Zeichenkette auf einen Typ für diesen Zweck zuordnen Ich verwende eine Karte –