2016-05-03 12 views
8

Nach this Lesen habe ich versucht, eine solche Umwandlung mit static_cast machen:static_cast Konvertierungskonstruktor vs Conversion Operator

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; 
} 

ich erwartet, dass es nicht kompilieren, weil beide Bauer und -betreiber gleiche c-v Qualifikation. Aber es kompiliert, erfolgreich und static_cast ruft Konstruktor anstelle von Operator. Warum?

(mit gcc 4.8.1 mit pedantic und Wall Flags kompiliert)

Antwort

7

Die C++ 11 Standard sagt (Hervorhebung von mir):

5.2.9 Static werfen

4 Andernfalls kann ein Ausdruck e explizit in einen Typ T mit einem static_cast der Form static_cast<T>(e)konvertiert werden, wenn die Erklärung T t(e); ist wohlgeformt, für einige erfundene temporäre Variable t (8.5). Die Auswirkung einer solchen expliziten Konvertierung ist die gleiche wie die Durchführung der Deklaration und Initialisierung und die anschließende Verwendung der temporären Variablen als Ergebnis der Konvertierung. Der Ausdruck e wird genau dann als glvalue verwendet, wenn die Initialisierung ihn als glvalue verwendet.

5 Andernfalls muss static_cast eine der unten aufgeführten Konvertierungen durchführen. Keine andere Konvertierung darf explizit mit einer static_cast durchgeführt werden.

Das erklärt, warum die static_cast in

B c = static_cast<B>(a); 

den Konstruktor von B Aufruf endet.

Der Konvertierungsoperator wird nur verwendet, wenn T t(e) nicht korrekt formatiert ist.

+0

Ich verstehe, dass dieser Satz bedeutet, dass, wenn 'B temporäre (a)' ist gültig 'static_cast' kann vorgeformt werden, aber ich sehe dort nicht, warum Konstruktor Vorrang hat. – PcAF

+0

@PcAF, Ich konnte keine Klausel finden, die besagt, dass 'static_cast' mit dem Konvertierungsoperator ausgeführt werden kann. Wenn es jedoch einen gibt, wird ihm eine niedrigere Priorität gegeben als oben. –

+0

@R Sahu Entferne 'B (const A &)' Konvertierungskonstruktor und jetzt 'static_cast' arbeitet mit Konvertierungsoperator. – PcAF