2014-11-09 16 views
37

Se si guarda alla grammatica per *declarator*s in §8/4 si noterà che un noptr-declarator può essere scritta come (ptr-declarator), cioè, può essere scritto come (declarator-id), che convalida le dichiarazioni come quelle in il titolo. Come infatti questo codice viene compilato senza problemi:Qual è lo scopo di una dichiarazione come int (x); o 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'; 
} 

Ma qual è lo scopo di consentire queste parentesi quando un puntatore (per un array o una funzione) non è coinvolto nella dichiarazione?

+13

Presumibilmente perché proibirli richiederebbe una grammatica più complessa. –

+0

Questa potrebbe essere una spiegazione. Non ci ho pensato. – Mao

+2

Analogamente, '(42)' è un'espressione valida anche se le parentesi non sono necessarie. –

risposta

52

Il fatto che questa regola sia applicabile nel tuo caso non è intenzionale: in definitiva è il risultato di mantenere la grammatica semplice. Non vi è alcun incentivo a vietare dichiarazioni come la vostra, ma ci sono grandi disincentivi a complicare le regole, specialmente se sono intricate come sono.

In breve, se non si desidera utilizzare questa sintassi inutilmente offuscata, non farlo.
C++ raramente obbliga a scrivere codice leggibile.

Sorprendentemente ci sono scenari in cui le parentesi possono salvare il giorno, però:

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

Non potresti dare una piccola spiegazione su 'friend std :: string (:: foo)();' dichiarazione? Cosa abbiamo effettivamente dichiarato e perché? –

+3

@DmitryFucintv: la dichiarazione vuole dichiarare l'istanza di 'foo' dichiarata nella prima riga come' amico' della struct 'Barra'. Per dichiarare una funzione come amica, devi fornire il suo tipo e argomenti di ritorno. Ma dire 'friend std :: string foo()' non funzionerà, poiché per l'uso non qualificato, quel 'foo' è nascosto da 'un altro'' pippo'. Quindi si deve qualificare 'foo' dal qualificatore globale' :: '. Ma questo dà la prima forma visualizzata, che soffre di ambiguità con la designazione di un membro (inesistente) di 'std :: string'. Una coppia di parentesi attorno a ':: foo' serve per evitare l'ambiguità –

4

che stai chiedendo la domanda sbagliata. La domanda corretta è:

Qual è lo scopo di non consentire tale dichiarazione?

La risposta è: non c'è nessuno .

Quindi, dato che questa sintassi è consentita come un effetto collaterale delle regole altrove, questo è ciò che ottieni.

+1

Una ragione per non consentire una tale dichiarazione è che al momento l'istruzione' T (x); 'è la dichiarazione di una variabile' x' di tipo 'T' , piuttosto che un'espressione cast funzionale di 'x' per digitare' T' (fatto esclusivamente per i suoi effetti collaterali), che è quello che sembra. – jchl

+0

@jchl: _ "fatto esclusivamente per i suoi effetti collaterali" _ C'è il tuo problema –

Problemi correlati