2016-01-25 47 views
5

mi chiedo, perché non è permesso di scrivere:Dichiarazione e dichiarazione con definizione. Perché questo non è permesso?

struct foo {  
    void bar();          // declaration 
    void bar(){std::cout << "moo" << std::endl;} // declaration + definition 
}; 

La funzione è dichiarata due volte (ho pensato che questo è ok) e definito una volta. Tuttavia, il mio compilatore si lamenta:

decldef.cxx:7:10: error: 'void foo::bar()' cannot be overloaded 

Perché non è permesso?

Perché il mio compilatore (g ++ 4.7.2) lo interpreta come sovraccarico?

PS: so come scriverlo "nel modo corretto", ma vorrei solo sapere, perché quanto sopra è sbagliato.

+0

In effetti, ma questa domanda è più profonda di questa, almeno secondo me. Ad esempio, se 'struct' è stato sostituito con' namespace', il codice è valido. – Bathsheba

+0

Buona domanda, davvero.La parte "+ definizione" è in realtà irrilevante; anche una dichiarazione ripetuta con firma identica non è consentita qui. – mindriot

risposta

10

Da §9.3

Fatta eccezione per le definizioni di funzioni membro che appaiono al di fuori di una definizione di classe, e fatta eccezione per specializzazioni esplicite di funzioni membro di modelli di classe e modelli funzione membro (14,7) che appaiono al di fuori della definizione della classe, una funzione membro non deve essere redeclared.

Inoltre, in questo caso le istruzioni possono anche cadere fallo di:

Una funzione membro può essere definita (8.4) nella sua definizione di classe, nel qual caso si tratta di una funzione membro inline (7.1.2), oppure può essere definito al di fuori della sua definizione di classe se ha già stato dichiarato ma non definito nella sua definizione di classe.

Poiché la prima dichiarazione non dichiara la funzione come inline. La seconda definizione lo fa implicitamente.

Tuttavia, quello su riflessione sembra meno convincente.

+3

Se questa è la risposta corretta, perché 'struct foo {void bar(); barra del vuoto(); }; 'fallisce con lo stesso messaggio di errore? – DevSolar

+0

@DevSolar aggiornato per rispondere alla tua domanda. –

+4

La seconda parte che hai citato è ciò che risponde veramente alla domanda; "Una funzione membro non può essere ridichiarata_". La differenza di inlining non ha molta importanza in questo contesto. – mindriot

5

La funzione è dichiarata due volte (ho pensato che sia ok) e definita una volta.

Questo è indipendente dal fatto che si definisca o meno la funzione la seconda volta. Il punto è che tu sei che dichiara la funzione due volte, e che è non OK.

Questo non viene compilato o, con lo stesso messaggio di errore:

struct foo { 
    void bar(); 
    void bar(); 
}; 

Tu non puoi ri-dichiarare la stessa funzione con lo stesso elenco di parametri all'interno della definizione di classe:

'void foo::bar()' cannot be overloaded with 'void foo::bar()'. 
+0

Infatti. Quindi c'è una dichiarazione esplicita nello standard da qualche parte che dice _why_ questo non è permesso? A mio parere, il messaggio di errore del compilatore è nel migliore dei casi fuorviante, dal momento che questo non è davvero un sovraccarico ... – mindriot

+0

@mindriot: Richard Hodges ha (modificato) la citazione. Non ho una copia dello standard C++ a portata di mano. – DevSolar