1

ich ziemlich überrascht bin, dass diese struct, die nur explizit umwandelbar bool ist, in einer if Anweisung funktioniert:Explizite und implizite Konvertierung

struct A 
{ 
    explicit operator bool() const 
    { 
     return m_i % 2 == 0; 
    } 

    int m_i; 
}; 

int main() 
{ 
    A a{ 10 }; 

    if (a) // this is considered explicit 
    { 
     bool b = a; // this is considered implicit 
        // and therefore does not compile   
    }   
    return 0; 
} 

Warum ist es so? Was ist der Entwurfsgrund im C++ Standard? Ich persönlich finde die zweite Konvertierung expliziter als die erste. Um es noch deutlicher, hätte ich den Compiler erwartet zwingt die folgenden haben für beide Fälle:

int main() 
{ 
    A a{ 10 }; 

    if ((bool)a) 
    { 
     bool b = (bool)a; 
    }   
    return 0; 
} 
+0

Ja, innerhalb 'if' ist wie eine explizite Konvertierung zu bool. (Sie können nicht expliziter sein als 'if' in' bool' zu konvertieren!). http://en.cppreference.com/w/cpp/language/explicit – alfC

Antwort

2

§ 6.4 Auswahlanweisungen [stmt.select]

  1. Der Wert einer Bedingung, bei der es sich um einen Ausdruck handelt, ist der Wert des Ausdrucks , der für andere Anweisungen als switch in bool konvertiert wurde.

§4 Standard-Conversions [CONV]

Bestimmte Sprachkonstrukte erfordern, dass ein Ausdruck zum ein Boolescher Wert umgewandelt werden. Ein Ausdruck e in einem solchen Kontext erscheint gesagt wird kontextuell umgewandelt werden in bool und wohlgeformt ist, wenn und nur wenn die Erklärung bool t(e); wohlgeformt ist, für einige temporäre Variable t erfunden (8.5).

So ist der Ausdruck der Bedingung in if muss kontextuell umwandelbar bool sein, was bedeutet, dass explizite Konvertierungen sind nicht zulässig.

Dies ist Modus am meisten getan wahrscheinlich, weil der Zustand der ifkann nur in einen Booleschen Wert bewerten, so von if(cond) sagen Sie explizit sind unter Angabe Sie wollen cond in einen Booleschen Wert ausgewertet werden.

+0

Danke, ich habe noch nie von dem Konzept * contextual convertible * gehört. Können Sie Ihrer Antwort bitte hinzufügen, in welchen Fällen eine Conversion-Operation als kontextabhängig angenommen wird? – nyarlathotep108

+1

@ nyarlathotep108 als Bedingung für eine 'if'' while' 'for' Anweisung. Ansonsten müsste ich den gesamten Standard scannen. Und das geht über den Rahmen der Frage hinaus. – bolov

+2

@ nyarlathotep108 bei einem schnellen Scan gefunden: der Operand des logischen Negationsoperators ('! Op'), Operanden logischer Operatoren (z.B.' op1 && op2') des Bedingungsoperators '? : ', das Assert auf einem' static_assert', nein außer dem Spezifizierer. – bolov