2016-05-03 32 views
8

Dopo aver letto this ho provato a fare tale conversione con static_cast:costruttore di conversione static_cast vs operatore di conversione

class A; 

class B { 
     public: 
     B(){} 

     B(const A&) //conversion constructor 
     { 
       cout << "called B's conversion constructor" << endl; 
     } 
}; 

class A { 
     public: 
     operator B() const //conversion operator 
     { 
       cout << "called A's conversion operator" << endl; 
       return B(); 
     } 
}; 

int main() 
{ 
    A a; 

    //Original code, This is ambiguous, 
    //because both operator and constructor have same cv qualification (use -pedantic flag) 
    B b = a; 

    //Why isn't this ambiguous, Why is conversion constructor called, 
    //if both constructor and operator have same c-v qualification 
    B c = static_cast<B>(a); 
    return 0; 
} 

mi aspettavo che si compila, perché entrambi costruttore e operatore hanno lo stesso c-v qualificazione. Tuttavia ha compilato, con successo e static_cast chiamate costruttore anziché operatore. Perché?

(elaborato applicando gcc 4.8.1 con pedantic e Wall bandiere)

risposta

7

Il C++ 11 dice standard (sottolineatura mia):

5.2.9 Static gettato

4 Altrimenti, un'espressione e può essere convertita esplicitamente in un tipo T utilizzando un static_cast del modulo static_cast<T>(e)se il la dichiarazione T t(e); è ben strutturata, per alcune variabili temporanee inventate t (8.5). L'effetto di tale conversione esplicita è lo stesso che eseguire la dichiarazione e l'inizializzazione e quindi utilizzare la variabile temporanea come risultato della conversione. L'espressione e viene utilizzata come glvalue se e solo se l'inizializzazione la utilizza come glvalue.

5 Altrimenti, lo static_cast deve eseguire una delle conversioni elencate di seguito. Nessun'altra conversione deve essere eseguita esplicitamente usando uno static_cast.

che spiega il motivo per cui il static_cast in

B c = static_cast<B>(a); 

finisce per chiamare il costruttore di B.

L'operatore di conversione viene utilizzato solo se lo T t(e) non è ben formato.

+0

Capisco che questa frase significa che se 'B temporaneo (a)' è valido 'static_cast' può essere preformato, ma non vedo lì perché il costruttore ha la precedenza. – PcAF

+0

@PcAF, non sono riuscito a trovare una clausola che dice che il 'static_cast' può essere eseguito usando l'operatore di conversione. Tuttavia, se ce n'è uno, viene data precedenza più bassa di quanto sopra. –

+0

@R Sahu Rimuovi il costruttore di conversione 'B (const A &)' e ora 'static_cast' funziona con l'operatore di conversione. – PcAF