2015-08-19 42 views
22

Per me un pair è proprio caso particolare di un tuple, ma in seguito mi sorprende:Perché l'inizializzazione = {} non funziona per la tupla?

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 

Perché c'è differenza quando usiamo {} inizializzare tuple?

ho provato anche g++ -std=c++1y ma ha ancora l'errore:

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

Si dovrebbe essere in grado di eseguire 'auto t2 = tupla {1, 2};' se si desidera la sintassi di inizializzazione della copia. Re l'errore, il messaggio di errore dice tutto. –

risposta

23

Il tuple constructor si sta cercando di chiamare è explicit, così copy-list-initialization will fail. Il corrispondente pair constructor non è explicit.

modificare il codice per

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

e si metterà a compilare.

+2

C'è qualche ragione per cui 'tuple' usa il costruttore esplicito? – Deqing

+2

@Deqing Se così non fosse, allora una 'tupla' contenente un singolo tipo potrebbe essere costruita implicitamente da un valore che è convertibile in quel tipo. – Praetorian

+1

@Praetorian Per evitare ciò, forse la tupla potrebbe avere un costruttore esplicito che accetta un argomento e un costruttore non esplicito che ne prende due o più? –

21

Oltre a Praetorian'scorrect answer (che ho upvoted), ho voluto aggiungere un po 'più di informazioni ...

Post-C++ 14, il principio è stato modificato per consentire:

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

per compilare e avere la semantica prevista. La proposta che fa questo è N4387. Ciò consentirà anche costrutti quali:

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

Esso consente solo se tutti T nel tuple sono implicitamente contructible da tutti gli argomenti.

Come estensione non conforme, libC++ implementa già questo comportamento.

+1

Si dice "non conforme": questa estensione modifica il comportamento di qualsiasi codice corretto in C++ 14? –

+7

@MattMcNabb: Sì. 'is_convertible > {}' è falso in C++ 14 e true in C++ 1z. I poteri dell'introspezione C++ sono diventati così forti che oggi è quasi impossibile scrivere estensioni conformi. –