Ich bin daran interessiert, eine Java-ähnliche Umgebung für C ++ zu implementieren. Ich weiß, das ist keine gute Idee und so weiter, aber ich möchte es später nicht wirklich benutzen, sondern nur lernen, wie man fortgeschrittene OOP macht.
Mein Problem ist, dass ich eine Basisklassenvorlage collection<T>
mit rein virtuellen Funktionen haben möchte. Eine dieser Funktionen sollte map()
sein, was ein std::function<R(T)>
erfordert. Da map()
virtuell sein sollte, weiß ich nicht, welchen Rückgabetyp ich dafür verwenden sollte. collection<R>
ist nicht möglich, da Memberfunktionsvorlagen nicht virtuell sein können.
Wie kann ich eine solche map()
-Memberfunktion für meine collection<T>
-Schnittstelle hinzufügen?
Wie kann ich eine solche
map
-Memberfunktion für meinecollection<T>
-Schnittstelle hinzufügen?
Die kurze Antwort ist: Sie nicht. Wenn ich etwas collection<int>
habe und ich möchte map
std::to_string
darauf haben, muss ich ein collection<std::string>
erzeugen. Aber ein vector_collection<int>
muss ein vector_collection<std::string>
erzeugen und ein list_collection<int>
muss ein list_collection<std::string>
erzeugen - damit die Typentransformation selbst virtual
sein muss. Sie können jedoch keine virtual
-Memberfunktionsvorlagen haben, daher gibt es keine Möglichkeit, dies auszudrücken.
Damit dies funktioniert, müssten Sie einen gemeinsamen Basistyp für alle Objekte haben, die Sie in Ihren Container einfügen, und dann nur eine gemeinsame Fassade haben, zwischen der Sie wechseln können. Das heißt, du hast wirklich nur collection<unique_ptr<Object>>
, wobei map
dir nur eine andere collection<unique_ptr<Object>>
gibt, und du nur map
deine collection_facade<int, collection<unique_ptr<Object>>>
in eine collection_facade<std::string, collection<unique_ptr<Object>>>
. Mit viel Arbeit und völliger Missachtung von Leistung und Typensicherheit könnten Sie dorthin gelangen.
Dies ist der Vorteil von Vorlagen. Wenn ich map
für etwas wie vector
schreiben möchte, kann ich das einfach schreiben:
oder:
%Vor% Ich muss map()
für jeden Container separat implementieren - aber ich müsste das trotzdem machen. Und jetzt gebe ich nichts auf. Außerdem, wie oft schreiben Sie Algorithmen, die Laufzeit-Container-Agnostic sind?
Implementieren Sie map
als externe Vorlagenfunktion.
Zum Beispiel können Sie map
in zwei Stufen zerlegen, interner virtueller Produzent und externer Vorlagenbenutzer.
Um im Wesentlichen komplizierte Container und monadische Kompositionen zu implementieren, können Sie begin()
und end()
sogar ablehnen und eine explizite (teilweise) Template-Spezialisierung schreiben.
Tags und Links c++ functional-programming oop templates