Das meiste ärgerliche Parse: warum nicht A a (()); Arbeit?

Unter den vielen Dingen, Stack Overflow, hat mich gelehrt, es ist, was ist bekannt als die "most vexing parse", die klassisch demonstrierten mit einer Zeile wie

A a(B()); //declares a function

Während dies für die meisten, intuitiv zu sein scheint, die Erklärung eines Objekts a Typ A, wobei eine vorübergehende B - Objekt als Konstruktor-parameter, es ist eigentlich eine Erklärung der Funktion a Rückkehr A, wobei ein Zeiger auf eine Funktion, die zurückgibt B und selbst benötigt keine Parameter. Ebenso die Linie

A a(); //declares a function

fällt auch unter die gleiche Kategorie, da statt einem Objekt, eine Funktion deklariert. Nun, im ersten Fall, der übliche workaround für dieses Problem ist das hinzufügen von einen zusätzlichen Satz von Klammern/Klammern um die B(), da der compiler dann interpretieren Sie es als die Deklaration eines Objekts

A a((B())); //declares an object

Jedoch im zweiten Fall, das gleiche zu tun, führt zu einem compile-Fehler

A a(()); //compile error

Meine Frage ist, warum? Ja, ich bin mir sehr wohl bewusst, dass die richtige 'workaround' ist zu ändern, um A a;, aber ich bin neugierig zu wissen, was es ist, dass die zusätzlichen () bedeutet, dass der compiler im ersten Beispiel, die dann nicht funktioniert, wenn das erneute anwenden es im zweiten Beispiel. Ist die A a((B())); Abhilfe einer bestimmten Ausnahme in der SCHRIFTLICHEN standard?

Kommentar zu dem Problem
(B()) ist nur eine C++ - Ausdruck, nichts mehr. Es ist nicht jede Art von Ausnahme. Der einzige Unterschied ist, dass es macht ist, dass es gibt keine Möglichkeit, kann es evtl. analysiert, wie eine Art, und so ist es nicht. Kommentarautor: Pavel Minaev
Es sollte auch darauf hingewiesen werden, dass der zweite Fall, Ein(); ist nicht der gleichen Kategorie. Für die compiler, es gibt keine andere Weise, Sie zu analysieren: Ein Initialisierer an diesem Ort besteht niemals mit leeren Klammern, so ist dies immer eine Funktionsdeklaration. Kommentarautor: Johannes Schaub - litb
litb ausgezeichneten Punkt ist ein subtiler, aber wichtiger, und das ist zu betonen - der Grund für die Mehrdeutigkeit besteht, die in dieser Erklärung 'A A(B())' ist in der Analyse der " B()' -> es kann sowohl ein Ausdruck & Erklärung & der compiler muss 'pick' decl über expr - also, wenn B() ist ein decl dann 'a' kann nur ein func decl (und nicht um eine variable decl). Wenn '()' werden durfte, eine Initialisierung 'A A()' wäre zweideutig - aber nicht expr vs decl, aber var decl vs func-decl - es gibt keine Regel zu bevorzugen decl über einen anderen - und so '()' ist nur nicht erlaubt einen Initialisierer hier - und die Mehrdeutigkeit nicht steigen. Kommentarautor: Faisal Vali
Ein(); ist nicht ein Beispiel most vexing parse. Es ist einfach eine Funktion, die Erklärung, genau wie in C. Kommentarautor: Pete Becker
"die richtige" workaround " ist, um es ändern zu A;" ist falsch. Das wird nicht geben Sie die Initialisierung der ein POD-Typ. Um intitialization schreiben {};. Kommentarautor: Cheers and hth. - Alf

InformationsquelleAutor der Frage GRB | 2009-09-15

Schreibe einen Kommentar