std::initializer_list als Funktion argument
Aus irgendeinem Grund dachte ich C++0x erlaubt std::initializer_list
als Funktions-argument für die Funktionen, die erwarten, dass Arten, die von konstruiert werden kann, wie zum Beispiel std::vector
. Aber anscheinend, funktioniert es nicht. Ist das nur mein compiler, oder wird das nie funktionieren? Ist es wegen der möglichen überlastung der Auflösung Probleme?
#include <string>
#include <vector>
void function(std::vector<std::string> vec)
{
}
int main()
{
//ok
std::vector<std::string> vec {"hello", "world", "test"};
//error: could not convert '{"hello", "world", "test"}' to 'std::vector...'
function( {"hello", "world", "test"} );
}
InformationsquelleAutor der Frage fredoverflow | 2010-03-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
GCC hat einen bug. Die Norm macht diese gültig. Siehe:
Feststellen, dass es zwei Seiten dieses
Die erste Frage wird beantwortet im Abschnitt
8.5
. Die zweite Frage wird beantwortet im Abschnitt13.3
. Für Beispiel -, Referenz-Bindung behandelt8.5.3
und13.3.3.1.4
während die Liste der Initialisierung erfolgt in8.5.4
und13.3.3.1.5
.8.5/14,16
:Wenn man die Kandidaten
function
der compiler wird eine Initialisierer-Liste (die keine Typ noch - es ist nur ein grammatikalisches Konstrukt!) als argument, und einstd::vector<std::string>
als parameter derfunction
. Um herauszufinden, was die Kosten für die Umwandlung ist, und ob wir kann konvertieren Sie diese in Zusammenhang mit der überbelastung13.3.3.1/5
sagt13.3.3.1.5/1
:13.3.3.1.5/3
:Nicht-Aggregat-Klasse
X
iststd::vector<std::string>
und ich werde herausfinden, die beste Konstruktor unten. Die Letzte Regel gewährt uns um benutzerdefinierte Konvertierungen in Fällen wie die folgenden:Dürfen wir konvertieren den string-literal zu
std::string
auch wenn dies benötigt eine benutzerdefinierte Konvertierung. Allerdings verweist er auf die Einschränkungen des anderen Absatz. Was bedeutet13.3.3.1
sagen?13.3.3.1/4
die den Absatz verantwortlich für ein Verbot mehrere benutzerdefinierte Konvertierungen. Wir werden nur einen Blick auf die Liste der Initialisierungen:Beachten Sie, dass dies eine wichtige Einschränkung: Wenn es nicht für diese, die oben genannten können mit dem copy-Konstruktor zu etablieren, die einem ebenso gut Konvertierung Sequenz, und die Initialisierung wäre mehrdeutig. (beachten Sie die mögliche Verwirrung von "A oder B und C" in dieser Regel: Es ist gemeint, zu sagen: "(A oder B) und C" - wir sind also eingeschränkt nurwenn Sie versuchen zu konvertieren, indem Sie einen Konstruktor von X mit einem parameter vom Typ
X
).Sind wir Delegierte zu
13.3.1.7
für die Erhebung der Konstruktoren, die wir verwenden können, diese Umwandlung zu tun. Nähern wir uns dieser Absatz von der Allgemeinen Seite ab8.5
die Delegierten uns8.5.4
:8.5.4/1
:8.5.4/2
:8.5.4/3
:Zu diesem Zeitpunkt
T
- Klasse ist der Typstd::vector<std::string>
. Wir haben ein argument (das nicht eine Art noch nicht! Wir sind nur im Zusammenhang mit einer grammatischen Initialisierungsliste). Konstruktoren sind aufgezählt als von13.3.1.7
:Werden wir nur berücksichtigen, der Initialisierungsliste des
std::vector
als der einzige Kandidat, da wir bereits wissen, die andere nicht gewinnen gegen Sie oder passen nicht das argument. Es hat die folgende Signatur:Nun, die Regeln der Umwandlung einer Initialisierungsliste ein
std::initializer_list<T>
(zur Kategorisierung der Kosten der argument/parameter-Konvertierung) sind aufgezählt in13.3.3.1.5
:Nun, der Initialisierungsliste werden erfolgreich umgewandelt, und die Umwandlung Reihenfolge ist eine benutzerdefinierte Konvertierung (von
char const[N]
zustd::string
). Wie dies gemacht wird, ist eine detaillierte8.5.4
wieder:Sehen
8.5.4/4
wie dieser Letzte Schritt ist gemacht 🙂InformationsquelleAutor der Antwort Johannes Schaub - litb
Scheint es so zu arbeiten:
Vielleicht ist es ein compiler-Fehler, aber vielleicht sind Sie gefragt, denn zu viele implizite Konvertierungen.
InformationsquelleAutor der Antwort UncleBens
Offhand bin ich mir nicht sicher, aber ich vermute, was hier passiert ist, dass die Umwandlung zu einer initializer_list ist eine Konvertierung und die Umwandlung dieser vector ist eine weitere Umrechnung. Wenn das der Fall ist, bist du ein überschreiten der Grenze nur eine implizite Konvertierung...
InformationsquelleAutor der Antwort Jerry Coffin
Dies ist entweder ein compiler-bug oder dein compiler nicht unterstützt std::initializer_list. Getestet auf GCC 4.5.1 und es kompiliert in Ordnung.
InformationsquelleAutor der Antwort Ricky65
Müssen Sie angeben, geben Sie Ihre initializer_list
Glück
InformationsquelleAutor der Antwort fnc12