Schnittstelle mit Template-Member-Funktion

8

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?

    
Exagon 15.05.2016, 09:40
quelle

2 Antworten

7
  

Wie kann ich eine solche map -Memberfunktion für meine collection<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:

%Vor%

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?

    
Barry 19.05.2016, 14:28
quelle
0

Implementieren Sie map als externe Vorlagenfunktion. Zum Beispiel können Sie map in zwei Stufen zerlegen, interner virtueller Produzent und externer Vorlagenbenutzer.

%Vor%

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.

    
bipll 19.05.2016 12:23
quelle