C ++ grundlegende Konstruktorfrage

8

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?

Bearbeiten:

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?

    
Yippie-Ki-Yay 08.07.2010, 15:27
quelle

4 Antworten

6

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.

    
jon-hanson 08.07.2010, 15:35
quelle
1

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.

    
Stephen 08.07.2010 15:40
quelle
1

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.

    
Dummy00001 08.07.2010 15:50
quelle

Tags und Links