2015-02-12 10 views
6

stavo attraversando C++11 standard draft qualche tempo fa e sono imbattuto in questo uno (in §8.3.6, p 204).:C++ - Dichiarazioni di funzioni all'interno degli ambiti di funzione?

void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow 

// a parameter with a default argument 
void f(int, int); 
void f(int, int = 7); 
void h() { 
    f(3); // OK, calls f(3, 7) 
    void f(int = 1, int); // error: does not use default 
    // from surrounding scope 
} 
void m() { 
    void f(int, int); // has no defaults 
    f(4); // error: wrong number of arguments 
    void f(int, int = 5); // OK 
    f(4); // OK, calls f(4, 5); 
    void f(int, int = 5); // error: cannot redefine, even to 
    // same value 
} 
void n() { 
    f(6); // OK, calls f(6, 7) 
} 

questo ha avuto a che fare con argomenti di default alle funzioni. Ciò che mi ha colpito è il fatto che le dichiarazioni di funzione sono apparse nell'ambito della funzione. Perché? A cosa serve questa caratteristica?

+0

L'ho usato per dichiarare una funzione che so che verrà chiamata solo all'interno dell'ambito. – Atul

+0

La risposta breve è che viene usata raramente. In teoria, potrebbe essere utile se (per esempio) avessi una variabile e una funzione con lo stesso nome. Una dichiarazione in un ambito interno ne nasconderà una in un ambito esterno. –

risposta

5

Sebbene non avessi idea di poterlo fare, l'ho testato e funziona. Credo che si può usare per le funzioni definite in seguito al futuro dichiarare, come di seguito:

#include <iostream> 

void f() 
{ 
    void g(); // forward declaration 
    g(); 
} 

void g() 
{ 
    std::cout << "Hurray!" << std::endl; 
} 

int main() 
{ 
    f(); 
} 

Se si rimuove la dichiarazione in avanti, il programma non verrà compilato. In questo modo è possibile avere una sorta di visibilità delle dichiarazioni anticipate basate sull'ambito.

+0

Hmm, OK, potrebbe diventare utile un po 'di tempo! :) –

+2

@HenriKorpela Devo dire che non ho mai saputo nulla di questo, e non credo che userò mai un "film" del genere. Preferirei molto essere in grado di ** definire ** funzioni all'interno di altre funzioni, senza la necessità del solito trucco del wrapping come 'static' all'interno di' struct/class'. – vsoftco

+0

Hai mai sentito parlare di un parassita irritante? È possibile dichiarare accidentalmente una funzione piuttosto che un'istanza. La gente di solito pensa 'Foo f();' dichiara e chiama il costruttore predefinito per 'f', ma dichiara invece una funzione. – 0x499602D2

0

Qualsiasi dichiarazione di funzione/variabile ha la sua visibilità e portata. Ad esempio, se in classe, solo i membri della classe possono vederlo. Se in funzione solo la funzione può avere visibilità, dopo aver dichiarato la variabile o la funzione.

Generalmente utilizziamo strutture dati nell'ambito della funzione. Ma la regola grammaticale del compilatore è applicabile ad entrambi, poiché la funzione in sé ha un indirizzo e quindi anche la visibilità è applicabile ad esso.

+0

Ma è comunque possibile chiamare la funzione da qualsiasi altro funzione che è definita al di sotto di essa, quindi basta nasconderlo dall'alto (non è possibile ** definire ** la funzione all'interno di un'altra funzione) – vsoftco

+0

Sì, si tratta essenzialmente dell'ambito. – Atul

+0

Questo è quello che non penso sia vero. Non riguarda interamente l'ambito, poiché l'ambito esterno può ancora utilizzare la funzione, poiché è necessario definire la funzione nell'ambito globale (ad eccezione, ovviamente, dei membri della classe). Solo le funzioni dichiarate sopra non possono usarlo. – vsoftco