2013-07-25 8 views
5

Questo mi ha sorpreso. Questo funziona:C++ Funzione amico inline con lo stesso nome della variabile membro

struct foo { 
    int x; 
    friend int x(foo f) { return f.x; } 
    friend int y(foo f); 
}; 

int y(foo f) { return x(f); } // no problem 

Ma questo è un errore:

struct foo { 
    int x; 
    friend int x(foo f) { return f.x; } 
    friend int y(foo f) { return x(f); } // error: invalid use of foo::x data member 
}; 

Perché non sono entrambi questi (dis) ammessi?

+1

Does 'return :: x (f);' funziona? Questo dovrebbe esplicitamente fare riferimento a 'x()' nel namespace globale. (Se 'x()' non è nello spazio dei nomi globale, prova ':: the :: namespace :: x (f)'.) – cdhowie

+0

@cdhowie: "Il nome dell'amico ** non viene trovato ** da non qualificato ricerca ** o per ricerca qualificata ** fino a quando non viene fornita una dichiarazione corrispondente in quell'ambito dello spazio dei nomi ". La ricerca dipendente dall'argomento è l'unico modo per trovarla, o aggiungere una dichiarazione sopra la classe (poiché sotto la classe è troppo tardi per trovare una dichiarazione inline di 'friend int y()' per trovarla) –

+1

Che tipo di convenzioni di denominazione portano a una variabile membro e una funzione amico per condividere un nome? Questo è il problema che devi veramente risolvere. –

risposta

3

La ragione è che nel primo caso, l'amicizia ha iniettato la dichiarazione di funzione nello spazio dei nomi che la racchiude, quindi la chiamata globale a x può vedere solo uno x.

Nel secondo esempio, x ha due significati in quel campo di applicazione: La funzione amico globale e la variabile (che ombreggia presumibilmente la funzione amico globale).

+2

Secondo http://stackoverflow.com/a/8284809/103167, no non si può chiamarlo come ':: x (f)'. –

+1

Ben è corretto, a meno che tu non fornisca anche una dichiarazione a livello di spazio dei nomi, puoi solo raggiungere la funzione amico tramite ADL. –

Problemi correlati