2012-09-09 29 views
6

Diamo questo codice:C++: cast operatore vs. operatore di assegnazione contro priorità costruttore conversione

Test1 t1; 
Test2 t2; 
t1 = t2; 

Credo che ci siano tre modi per implementare t1 = t2

  • a (o più?) operatore sovraccarico assegnare in Test1
  • sovraccaricare tipo operatore cast in Test2
  • per creare Test1(const Test2&) conversione costruttore

Secondo il mio test GCC, questa è la priorità di ciò che viene utilizzato:

  1. operatore assegnazione
  2. conversione costruttore e operatore cast di tipo (ambiguo)
  3. const costruttore conversione e operatore di tipo const (ambiguo)

Per favore aiutami a capire perché questa priorità.

Io uso questo codice per il test (decommentare alcune linee per provare)

struct Test2; 
struct Test1 { 
    Test1() { } 
    Test1(const Test2& t) { puts("const constructor wins"); } 
// Test1(Test2& t) { puts("constructor wins"); } 
// Test1& operator=(Test2& t) { puts("assign wins"); } 
}; 

struct Test2 { 
    Test2() { } 
// operator Test1() const { puts("const cast wins"); return Test1(); } 
// operator Test1() { puts("cast wins"); return Test1(); } 
}; 


int main() { 
    Test1 t1; 
    Test2 t2; 
    t1 = t2; 
    return 0; 
} 
+0

'Test1 :: Test1 (const Test2 &)' non è un "costruttore di copie", è un "costruttore di conversione". – aschepler

+0

Questo post spiega esattamente perché l'operatore di conversione ha una precedenza più alta: http://stackoverflow.com/questions/1384007/conversion-constructor-vs-conversion-operator-precedence –

risposta

13

La dichiarazione t1 = t2; è equivalente a:

t1.operator=(t2); 

Ora si applicano le normali regole di risoluzione di sovraccarico. Se c'è una corrispondenza diretta, questa è la scelta. In caso contrario, le conversioni implicite vengono considerate per l'uso con l'operatore di assegnazione della copia (generato automaticamente, "implicitamente definito").

Ci sono due possibili conversioni implicite, definite dall'utente. Tutte le conversioni definite dall'utente contano uguali, e se entrambi sono definiti, il sovraccarico è ambigua:

  • Convertire t2 ad un Test1 tramite il costruttore Test1::Test1(Test2 const &) conversione.

  • Convertire t2 a Test1 tramite l'operatore di trasmissione Test2::operator Test1() const.

+0

Nel secondo esempio di ideone di @Luchian, la funzione di conversione vince perché lega un 'Test2 &' a 't2', non un' const Test2 & '. Pensavo che http://ideone.com/U38vK avrebbe dovuto essere ambiguo, ma sembra che g ++ preferisca il costruttore. – aschepler

+2

Aha. g ++ li chiama ambigui se chiedi '-pedantic'. G ++ predefinito di cattivo gusto. – aschepler

+0

@KerrekSB: se l'operatore di cast non è costante, batte il costruttore di conversioni e non c'è ambiguità. http://liveworkspace.org/code/7795254ae49b4d6350f0ede57615e4c6 –

Problemi correlati