Wie soll ich mit der folgenden Situation umgehen:
Ich schreibe meine eigene 2D-Vektorklasse und habe folgenden Code:
%Vor% Nun, wenn ich Vector2 v(3.0f, 4.0f);
sage, kompiliert es gut und ruft den passenden float-Konstruktor auf.
Aber wenn ich Vector2 v(3, 4);
schreibe, scheitert es, weil der Template-Konstruktor "besser passt" und Vector2(Iterator(3), Iterator(4))
heißt.
Was soll ich in diesem Fall tun?
Meine Idee war, die Methode assign(It1, It2)
member anstelle des Konstruktors einzuführen, aber vielleicht gibt es eine bessere Lösung?
Was denkst du auch über ASSERT(end - begin == 2)
line? Ich weiß, dass dies bedeutet, dass ich zB keine Iteratoren von std::list
weitergeben kann, aber zusätzliche Sicherheit bringt. Soll ich das tun oder nicht?
So etwas scheint zu funktionieren:
%Vor%Ich glaube, es benutzt SFINAE, um zu verhindern, dass der Compiler den zweiten ctor für nicht-numerische Typen auswählt.
Wie bei ASSERT (end - begin == 2)
sollten Sie std::distance(begin, end)
verwenden, um den Abstand zwischen zwei Iteratoren zu bestimmen.
EDIT: Ist das ein 2D-Vektor? Oder nur zwei Vektoren? Ich habe das für einen 2D-Vektor beantwortet.
Wie soll ich mit der folgenden Situation umgehen?
Ich denke, du solltest damit umgehen, indem du den float
-Konstruktor entfernst. Beim Lesen des Codes ist unklar, welche Art von Objekt Sie davon erwarten sollten.
Nach dem Lesen des Callsite-Codes hätte ich keinen Grund zu der Annahme, dass vector2 v2(1, 5);
einen Vektor aus zwei Vektoren mit jeweils einem Wert erzeugt.
Ich persönlich hätte erwartet, dass es eine 1x5
-Matrix erstellen würde.
Wenn dies ein häufiger Anwendungsfall für Ihre Bibliothek ist, ziehen Sie einen benannten Konstruktor :
%Vor%re: ASSERT
Das ASSERT ist eine nette Plausibilitätsprüfung, aber Ihr Iterator
muss zufälligen Zugriff unterstützen (oder zumindest Subtraktion, um die Entfernung zu finden). Dies könnte seine Verwendung übermäßig einschränken. Erwägen Sie die Verwendung von std::distance
oder die Überprüfung, dass local_vector_storage
später die Größe zwei hat.
Im konkreten Fall sehe ich keinen Sinn darin, das Vector2(Iterator begin, Iterator end)
c'tor überhaupt einzuführen.
Im Allgemeinen sehe ich keinen Sinn darin, das std::vector
nachzuahmen (was im Wesentlichen ein Wrapper für ein Array ist), wenn die Dimension von Vector2
fest ist und sich niemals ändert. Die Überlappung von Anwendungsfällen zwischen std::vector
und Vector2
ist vernachlässigbar bis nicht vorhanden: std::vector
wird oft von einem anderen Container initialisiert, während Vector2
mit zwei Werten oder mit einem anderen Vektor2 initialisiert wird .
Und selbst wenn Sie sich dazu entschließen, weiterzugehen, die Zeile:
%Vor%würde die Nützlichkeit des Konstruktors drastisch einschränken, da relativ wenige Iteratoren die Arithmetik unterstützen.
Tags und Links c++ constructor vector templates