2015-08-19 10 views
22

Für mich ein pair ist nur Spezialfall eines tuple, aber folgende überrascht mich:Warum = {} Initialisierung funktioniert nicht für Tupel?

pair<int, int> p1(1, 2); // ok 
tuple<int, int> t1(1, 2); // ok 

pair<int, int> p2={1, 2}; // ok 
tuple<int, int> t2={1, 2}; // compile error 

Warum Unterschied gibt es, wenn wir {} verwenden tuple zu initialisieren?

versuchte ich sogar g++ -std=c++1y aber immer noch Fehler hat:

a.cc: In function 'int main()': 
a.cc:9:29: error: converting to 'std::tuple<int, int>' from initializer list would use explicit constructor 'constexpr std::tuple<_T1, _T2>::tuple(_U1&&, _U2&&) [with _U1 = int; _U2 = int; <template-parameter-2-3> = void; _T1 = int; _T2 = int]' 
    tuple<int, int> t2={1, 2}; 
          ^
+1

Sie sollten in der Lage sein, 'auto t2 = tuple {1, 2}; 'zu tun, wenn Sie die Syntax der Kopierinitialisierung haben wollen. Re der Fehler, die Fehlermeldung sagt alles. –

Antwort

23

Die tuple constructor Sie versuchen explicit ist zu nennen, so copy-list-initialization will fail. Die entsprechende pair constructor ist nicht explicit.

Code ändern zu

tuple<int, int> t2{1, 2}; 

und es wird kompilieren.

+2

Gibt es einen Grund, dass 'Tupel' expliziten Konstruktor verwendet? – Deqing

+2

@Deqing Wenn dies nicht der Fall ist, könnte ein 'Tupel', das einen einzelnen Typ enthält, implizit aus einem Wert konstruiert werden, der in diesen Typ konvertierbar ist. – Praetorian

+1

@Praetorian Um das zu vermeiden, könnte Tupel vielleicht einen expliziten Konstruktor haben, der ein Argument nimmt, und einen nicht-expliziten Konstruktor, der zwei oder mehr braucht? –

21

Neben Praetorian'scorrect answer (was ich upvoted habe), habe ich ein wenig mehr Informationen ...

Post-C++ 14, der Standard geändert wurde hinzufügen wollte ermöglichen:

tuple<int, int> t2={1, 2}; 

zu kompilieren und haben die erwartete Semantik. Der Vorschlag, der dies tut, ist N4387. Dies wird auch Konstrukte lassen wie:

tuple<int, int> 
foo() 
{ 
    return {1, 2}; 
} 

Es erlaubt es nur, wenn alle T im tuple aus allen Argumente implizit contructible sind.

Als nicht konforme Erweiterung implementiert libC++ dieses Verhalten bereits.

+1

Sie sagen "nicht konform": ändert diese Erweiterung das Verhalten eines Codes, der unter C++ 14 korrekt ist? –

+7

@MattMcNabb: Ja. 'is_convertible > {}' ist falsch in C++ 14 und wahr in C++ 1z. Die Möglichkeiten der C++ - Introspektion sind so stark geworden, dass es heutzutage fast unmöglich ist, konforme Erweiterungen zu schreiben. –

Verwandte Themen