Ich weiß, dass man nicht eine virtuelle Vorlage Mitglied Funktion haben kann, aber ich möchte etwas ähnlich wie es funktioniert.Virtuelle Vorlage Mitglied Funktion
Betrachten Sie den folgenden Pseudo-Code:
struct abstract
{
template<typename T>
virtual T get() const = 0;
};
using abstract_pointer = std::shared_ptr<abstract>;
struct concrete_int : public abstract
{
template<>
int get() const { return 123; }
};
struct concrete_string : public abstract
{
template<>
std::string get() const { return "abc"; }
};
abstract_pointer factory()
{
// Some logic here to decide what concrete type to return
return ...;
}
void print_value(abstract_pointer p)
{
// Will print either 123 or "abc"
std::cout << "p = " << p->get() << '\n';
}
int main()
{
abstract_pointer p = factory();
print_value(p);
}
Der Hauptcode wird nur die Art abstract_pointer
verwenden, es soll nicht wirklich etwas über die konkreten Klassen kennen.
Es könnte leicht mit CRTP und Typ Abzug gelöst werden, aber dann ist es nicht wirklich möglich, das Objekt zu anderen Funktion wie im obigen Beispiel zu übergeben.
Ich könnte auch Boost Variante oder Gewerkschaften verwenden, aber dann könnte es schnell unhandlich werden, wenn mehr konkrete Klassen hinzugefügt werden. Ich könnte Boost auch verwenden, aber dann müsste ich any_cast
verwenden und es wäre nicht so ... nun, schön und einfach.
Es könnte sein, dass mein Google-Fu heute schlecht ist, oder ich bin einfach zu müde, aber ich habe es nicht wirklich gefunden. Ist es möglich, so etwas zu tun und gleichzeitig flexibel genug zu bleiben, um mehr konkrete Klassen hinzuzufügen und die Oberfläche einfach und schön zu halten?
Eine kleine Erklärung über den Anwendungsfall: Dies ist ein Teil eines kleinen Lexer für einen einfachen Compiler Ich mache (nur wenn zum Spaß) zu sein, und die abstrakte Klasse im Beispiel oben ist Die Klasse "Token" und die konkreten Klassen sind spezifische Token wie "Ganzzahl-Token" oder "Zeichenfolge-Token" oder "Bezeichner-Token".
Der Grund, warum ich abstrakte/konkrete Klassen und Vererbung verwenden möchte, ist, weil ich den lexer flexibel genug machen möchte, um von mehreren Sprachen verwendet zu werden, also sollte es einfach sein, ein Kind namens "identifier token" hinzuzufügen Klasse für "Keyword-Token" und vielleicht sogar eine konkrete Klasse für jedes Keyword.
Aber vielleicht AaronI ist richtig, dass ich versuche, etwas Komplexes zu machen. Ich lasse diese Frage stehen, für den Fall, dass jemand eine gute Lösung findet oder ein gutes Duplikat findet, während ich darüber nachdenke und nachdenke, ob ich selbst etwas Passendes finden kann.
Wann immer ich solche brauchte, griff ich auf CRTP zurück. Aber auch CRTP erlaubt abstrakte (nicht-templated) Basisklassen, um diese einfacher zu übergeben. Ich habe diesen Ansatz stark mit meinem [STTCL-Zustandsmaschine-Framework] (https://github.com/makulik/sttcl) verwendet. –
Vielleicht Check Boost.TypeErasure? –
kann das abstrakte Objekt nicht einfach den Besuch unterstützen? Es ist schwierig, die Anforderung zu verstehen, ohne den Anwendungsfall zu kennen. –