Dies ist eine ähnliche Frage zu Using std::forward on sub fields, aber die Antwort scheint nicht in meinem Fall zutreffen.Mit std :: forward bei Casted Argumenten
template<class Base, class F>
void visit(Base&&, const F&) {
throw std::bad_cast();
}
template<class Derived, class... Rest, class Base, class F>
void visit(Base&& base, const F& f) {
if (auto *as_derived = dynamic_cast<Derived *>(&base)) {
return f(std::forward<Base>(*as_derived));
} else {
return visit<Rest...>(std::forward<Base>(base), f);
}
}
Mein Ziel ist es, dass die folgende Testfallarbeit:
struct Animal {
virtual ~Animal() {}
};
struct Cat : Animal {
void speak() & { puts("meow"); }
void yowl() && { puts("MEOW!"); }
};
struct Dog : Animal {
void speak() & { puts("woof"); }
void yowl() && { puts("WOOF!"); }
};
int main() {
Animal *a = new Cat();
Animal *b = new Dog();
visit<Cat, Dog>(*a, [](auto&& a){ std::forward<decltype(a)>(a).speak(); });
visit<Cat, Dog>(*b, [](auto&& a){ std::forward<decltype(a)>(a).speak(); });
visit<Cat, Dog>(std::move(*a), [](auto&& a){ std::forward<decltype(a)>(a).yowl(); });
visit<Cat, Dog>(std::move(*b), [](auto&& a){ std::forward<decltype(a)>(a).yowl(); });
}
gewünschte Ausgabe: "Meow" "Miau" "Wuff" "SCHUSS!". Beachten Sie, dass die Funktionen speak
und yowl
nicht virtuell sind; Dies ist in meinem ursprünglichen Code erforderlich, da es sich tatsächlich um Vorlagen handelt und Vorlagen nicht virtuell sein können.
Das Problem mit diesem Code wie hier geschrieben ist, dass std::forward<Base>(*as_derived)
nicht nur die ref-Qualifiers und const-Qualifier auf *as_derived
ändern, um perfekte Weiterleitung zu ermöglichen; es wirft tatsächlich den Typ zurück zu Base&
, nerfing den ganzen Punkt von visit
!
Gibt es eine Standard-Library-Funktion, die das tut, was ich will std::forward
zu tun - nämlich, ändern Sie die ref-Qualifier und const-Qualifizierer auf *as_derived
diejenigen entsprechen, die von std::forward<Base>
perfekt-vorne abgeleitet sein würde?
Wenn es keine Standardbibliotheksfunktion gibt, wie könnte ich eine Funktion für die "perfekte Weiterleitung eines Kindtyps" für meinen eigenen Gebrauch schreiben?
Die obige Wandbox-Verbindung enthält etwas, das für diesen Testfall "funktioniert", aber es behält die Konstanz nicht und es sieht überhaupt nicht elegant aus.
Das ist viel schöner als die Auflistung aller cv-ref Sachen. – Barry