2014-11-09 10 views
37

Wenn man sich die Grammatik sucht *declarator*s in §8/4 werden Sie feststellen, dass ein noptr-declarator geschrieben werden kann (ptr-declarator), das heißt, es kann wie folgt geschrieben werden (declarator-id), die Erklärungen wie die, die überprüft in der Titel. Wie in der Tat stellt dieser Code ohne ein Problem:Was ist der Zweck einer Deklaration wie int (x); oder int (x) = 10;

#include <iostream> 
struct A{ int i;}; 
int (x) = 100; 
A (a) = {2}; 
int main() 
{ 
    std::cout << x << '\n'; 
    std::cout << a.i << '\n'; 
} 

Aber , was der Zweck zu erlauben, diese Klammern ist, wenn ein Zeiger (auf einen Array oder eine Funktion) in der Erklärung nicht beteiligt ist?

+13

Vermutlich, weil zu verbieten sie eine komplexere Grammatik erfordern würde. –

+0

Das könnte eine Erklärung sein. Ich habe nicht darüber nachgedacht. – Mao

+2

In ähnlicher Weise ist '(42)' ein gültiger Ausdruck, obwohl die Klammern unnötig sind. –

Antwort

52

Die Tatsache, dass diese Regel in Ihrem Fall anwendbar ist, ist nicht absichtlich: Es ist letztlich ein Ergebnis der Grammatik einfach zu halten. Es gibt keinen Anreiz, Deklarationen wie die Ihre zu verbieten, aber es gibt große Hemmnisse, die Regeln zu komplizieren, besonders wenn diese so kompliziert sind wie sie sind.

Kurz gesagt, wenn Sie diese unnötig verschleierte Syntax nicht verwenden möchten, nicht.
C++ zwingt Sie selten, lesbaren Code zu schreiben.

Überraschenderweise gibt es Szenarien, in denen Klammern den Tag retten können, aber:

std::string foo(); 

namespace detail 
{ 
    int foo(long); // Another foo 

    struct Bar 
    { 
     friend std::string ::foo(); // Doesn't compile for obvious reasons. 

     friend std::string (::foo)(); // Voilà! 
    }; 
} 
+0

Könnten Sie nicht etwas über 'friend std :: string (:: foo)() sagen; Was haben wir eigentlich erklärt und warum? –

+3

@DmitryFucintv: Die Deklaration möchte die Instanz von 'foo', die in der ersten Zeile deklariert ist, als 'Freund' der Struktur 'Bar' deklarieren. Um eine Funktion als Freund zu deklarieren, müssen Sie den Rückgabetyp und die Argumente angeben. Aber 'friend std :: string foo()' zu sagen, wird nicht funktionieren, da für unqualifizierte Verwendung dieses 'foo' durch 'ein anderes'' foo' verdeckt wird. Also muss man 'foo' durch den globalen Qualifier' :: 'qualifizieren. Aber das gibt die erste angezeigte Form, die an der Mehrdeutigkeit mit der Bezeichnung eines (nicht existenten) Mitgliedes von 'std :: string' leidet. Ein Paar Klammern um ':: foo' dient dazu, die Mehrdeutigkeit zu vermeiden. –

4

Sie die falsche Frage. Die richtige Frage lautet:

Was ist der Zweck, eine solche Deklaration zu verbieten?

Die Antwort ist: gibt es keine.

Also, vorausgesetzt, dass diese Syntax als Nebeneffekt der Regeln an anderer Stelle erlaubt ist, ist das, was Sie bekommen.

+1

Ein Grund, eine solche Deklaration zu verbieten, ist, dass zur Zeit die Aussage' T (x); 'die Deklaration einer Variablen' x' vom Typ 'T' ist , anstelle eines funktionalen Cast-Ausdrucks von 'x', um' T' (rein wegen seiner Nebeneffekte) zu schreiben, so wie es aussieht. – jchl

+0

@jchl: _ "rein wegen seiner Nebenwirkungen gemacht" _ Da ist dein Problem –

Verwandte Themen