2016-06-20 8 views
19

Poiché C++ 11, la conversione del restringimento non è consentita in list initialization (incluso aggregate initialization). Quindi, in pratica:Riduzione della conversione in coppia con inizializzazione rinforzata se il secondo attributo non è rinforzato-inizializzato

char c{1000}; // Does not compile with g++, clang, vc 

Ma:

std::pair<char, double> p{1000, 1.0}; 

compila con tutto il compilatore?

Ma:

std::pair<char, double> p{1000, {1.0}}; 

Non compilare con VC (errore C2398), dà un avvertimento con clangore e compila in silenzio con g ++ ...

mi sarei comportamento VC atteso in tutto il mondo, vale a dire un conversione restringimento non consentita che genera un errore. Qual è il compilatore giusto?


D'altra parte, nessuna delle dichiarazioni delle variabili nei seguenti frammenti di compilare:

struct X { 
    char c; 
    double d; 
}; 

X x1{999, 1.0}; 
X x2{999, {1.0}}; 

struct Y { 
    char c; 
    double d; 
    Y (char c, double d) : c(c), d(d) { } 
}; 

Y y1{999, 1.0}; 
Y y2{999, {1.0}}; 

Così una delle mia ipotesi può essere che ci sia qualcosa di speciale std::pair? Qualcosa che restringerebbe anche l'inizializzazione rinforzata?

+0

Con quale pedante hai impostato le impostazioni del compilatore? A quale versione standard li hai impostati? – user2357112

+3

Penso che la cosa sia che il restringimento non sta accadendo prima del costruttore; Penso che tu stia chiamando [costruttore 3] (http://en.cppreference.com/w/cpp/utility/pair/pair) qui, e il costruttore sta ricevendo un 'int' e sta facendo la conversione stessa. La conoscenza del mio avvocato di lingua non è abbastanza buona per confermare questo, però. – user2357112

+0

@ user2357112 Ho perso completamente il costruttore ... Questo spiegherebbe perfettamente il motivo per cui il primo codice viene compilato senza problemi (mentre la mia 'struct Y' personalizzata non funziona). Ma è ancora un mistero perché il secondo codice generi un avvertimento con clang e un errore con VC ... Non si dovrebbe chiamare lo stesso costruttore? – Holt

risposta

14
  1. std::pair<char, double> p{1000, 1.0}; non viene diagnosticata perché richiede l'template<class U1, class U2> pair(U1&&, U2&&) costruttore (con U1 == int e U2 == double), che corrisponde esattamente; il restringimento non avviene finché non entri nel corpo del costruttore.

  2. std::pair<char, double> p{1000, {1.0}}; non può chiamare quel costruttore, perché il rinforzato-init-list{1.0} è un contesto non dedotto, quindi non si può dedurre U2.

+0

Quindi "estensione" GCC è in contraddizione con lo standard e VC sarebbe quella corretta? – Holt

+0

Se creo una [classe con la stessa semantica del costruttore] (http://ideone.com/cBDKCA), la conversione del restringimento avviene ancora. C'è qualcos'altro che mi manca? Grazie :) – Rakete1111

+0

@ Rakete1111 Il tuo costruttore non ha la stessa semantica perché non è un modello (la tua classe è ma non il tuo costruttore). – Holt

Problemi correlati