Regeln für die bedingte Operator im Entwurf N3225 sagt an einer Stelle
Andernfalls ist das Ergebnis ein prvalue ist. Wenn der zweite und der dritte Operand nicht den gleichen Typ haben und entweder über eine (möglicherweise cv-qualifizierte) Klassenart verfügt, wird die Überladungsauflösung verwendet, um die Konvertierungen (falls vorhanden) auf die Operanden anzuwenden (13.3.1.2, 13.6). Wenn die Überladungsauflösung fehlschlägt, ist das Programm fehlerhaft. Andernfalls werden die so ermittelten Konvertierungen angewendet, und die konvertierten Operanden werden anstelle der ursprünglichen Operanden für den Rest dieses Abschnitts verwendet.
Bis zu diesem Punkt, jede andere Alternative (wie, um den einen Operanden zu konvertieren) gescheitert, so werden wir jetzt tun, was dieser Absatz sagt. Die Konvertierungen, die wir anwenden werden, werden durch die Überladungsauflösung bestimmt, indem a ? b : c
in operator?(a, b, c)
umgewandelt wird (ein imaginärer Funktionsaufruf zu einer so genannten Funktion). Wenn Sie schauen, was die Kandidaten für die imaginäre operator?
sind, finden Sie (unter anderem)
Für jeden Typ T, wobei T ein Zeiger, Zeiger-to-Mitglied oder scoped Aufzählungstyp, gibt es Bewerber Funktionen der Form
T operator?(bool, T , T);
Und dazu gehört auch ein Kandidat für die T
der Typ void(*)()
ist. Dies ist wichtig, da Lambda-Ausdrücke ein Objekt einer Klasse ergeben, die in einen solchen Typ konvertiert werden kann. Die Spezifikation sagt
Der Verschlusstyp für einen Lambda-Ausdruck ohne Lambda-Erfassung eine öffentliche nicht-virtuelle nicht-explizite const Umwandlungsfunktion die gleichen Parameter funktionieren Zeiger mit und Rückgabetypen wie der Funktion des Verschlusstypen Anruf Betreiber. Der Wert, der von dieser Konvertierungsfunktion zurückgegeben wird, ist die Adresse einer Funktion, die, wenn sie aufgerufen wird, den gleichen Effekt hat wie das Aufrufen des Funktionsaufrufoperators des Schließungstyps.
Die Lambda-Ausdrücke können nicht auf einen anderen der Parametertypen aufgelistet, konvertiert sein, die Überladungsauflösung bedeutet, erfolgreich ist, findet eine einzige operator?
und wird beide Lambda-Ausdrücke zu Funktionszeiger umwandeln. Der Rest des Bedingungsoperatorabschnitts wird dann wie üblich fortfahren, wobei er nun zwei Verzweigungen für den Bedingungsoperator desselben Typs aufweist.
Deshalb ist auch Ihre erste Version in Ordnung, und warum GCC es richtig annimmt. Allerdings verstehe ich nicht wirklich, warum Sie die zweite Version überhaupt zeigen - wie andere erklärt haben, macht es etwas anderes und es ist nicht überraschend, dass es funktioniert, während das andere nicht funktioniert (auf Ihrem Compiler). Beim nächsten Mal sollten Sie versuchen, keinen nutzlosen Code in die Frage aufzunehmen.
Welchen Compiler benutzen Sie und was sind die Warnungen/Fehler? – schnaader
Wie üblich, was ist die Fehlermeldung? – MSalters
@schnaader VS2010 sp beta1 –