Implizite Konvertierung von int in Vektor?

8

vector<T> hat einen Konstruktor, der die Größe des Vektors annimmt und, soweit ich weiß, explizit ist, was durch die Tatsache bewiesen werden kann, dass der folgende Code nicht kompiliert werden kann

%Vor%

Was ich nicht verstehen kann und bitte Sie zu erklären, warum der folgende Code kompiliert wird

%Vor%

Es kompiliert nicht nur, sondern skaliert den Graph tatsächlich auf 5 und setzt jedes Element auf einen Vektor mit fünf Nullen, d. h. macht dasselbe wie der Code, den ich normalerweise schreiben würde:

%Vor%

Wie? Warum?

Compiler: MSVC10.0

OK, es scheint ein MSVC-Bug (noch ein weiterer) zu sein. Wenn jemand in einer Antwort auf den Fehler eingehen kann (d. H. Die Fälle zusammenfassen, in denen er reproduziert wird), würde ich das gerne akzeptieren.

    
Armen Tsirunyan 07.05.2013, 20:25
quelle

4 Antworten

7

Es ist nicht wirklich ein Fehler. Die Frage ist, was schief gehen könnte, um den zweiten Teil des Codes zuzulassen, während der erste nicht kompiliert?

Das Problem ist, dass es Ihnen offensichtlich erscheint, welchen Konstruktor Sie aufrufen möchten, wenn Sie dies tun:

%Vor%

es ist nicht so klar für den Compiler. Insbesondere gibt es zwei Konstruktorüberladungen, die die Argumente möglicherweise akzeptieren können:

%Vor%

Die erste erfordert die Konvertierung von 5 nach size_type (was nicht signiert ist), während die zweite eine perfekte Übereinstimmung ist, so dass diese vom Compiler ...

übernommen wird

... aber der Compiler erfordert, dass die zweite Überladung, wenn der abgeleitete Typ InputIterator integral ist, sich so verhält, als wäre es ein Aufruf an:

%Vor%

Was der C ++ 03-Standard effektiv vorschreibt, ist, dass das zweite Argument explizit vom ursprünglichen Typ int in den Zieltyp std::vector<int> konvertiert wird. Da die Konvertierung explizit ist, erhalten Sie den Fehler.

Der C ++ 11-Standard ändert den Wortlaut so, dass SFINAE den Iterator-Konstruktor deaktiviert, wenn das Argument nicht wirklich ein Eingabe-Iterator ist. In einem C ++ 11-Compiler sollte der Code daher zurückgewiesen werden (was wahrscheinlich der Grund ist) habe behauptet, dies sei ein Fehler).

    
David Rodríguez - dribeas 07.05.2013, 20:55
quelle
2

Für mich sieht es so aus, als würde es diesen Konstruktor aufrufen:

%Vor%

Ich bin nicht sicher, wo explicit hineinkommt, weil der Konstruktor mehrere Parameter benötigt. Es wird nicht automatisch von einem Int in einen Vektor umgewandelt.

    
James Holderness 07.05.2013 20:43
quelle
1

Dies ist eigentlich eine Erweiterung, kein Bug.

Der Konstruktor, der aufgerufen wird, ist derjenige, der zwei Iteratoren benötigt (aber die Signatur wird tatsächlich mit zwei beliebigen Parametern des gleichen Typs übereinstimmen); Es ruft dann eine Spezialisierung auf, wenn die beiden Iteratoren tatsächlich int sind, wodurch explizit ein value_type mit dem Wert von end erstellt wird und der Vektor mit begin Kopien davon gefüllt wird.

    
Collin Dauphinee 07.05.2013 20:42
quelle
-4

std :: Vektor & lt; int & gt; hat einen Konstruktor, der size_type und const int & amp; akzeptiert. Dies ist der Konstruktor, von dem ich in diesem Fall erwarten würde, dass er den Vektor so initialisiert, dass er 5 Ints hat, jede mit dem Wert 5.

    
selalerer 07.05.2013 20:31
quelle