Dichiarazione di classe di amici e utilizzando la direttiva
-
21-12-2019 - |
Domanda
è il seguente esempio ben formato?
namespace N {
class A;
}
using namespace N;
class B {
int i;
friend class A;
};
namespace N {
class A {
B m;
int get() { return m.i; }
};
}
.
Questo esempio compilato correttamente con CLANG 3.5, ma non è riuscito con G ++ 4.8.1 con quanto segue:
main.cpp: In member function ‘int N::A::get()’:
main.cpp:7:9: error: ‘int B::i’ is private
int i;
^
main.cpp:14:30: error: within this context
int get() { return m.i; }
^
.
C ++ 11 Standard §7.3.1.2 P3 dice,
.Se il nome in una dichiarazione
friend
non è né qualificata né a template-ID e la dichiarazione è una funzione o un elaborato-tipo-specificatore , la ricerca per determinareSe l'entità è stata precedentemente dichiarata non è considerata non considerare ambiti al di fuori dello spazio dei nomi più intimi.
Nell'esempio, class A
non è membro di Innomist che allega il namespace (I.E. Global Namespace), ma class A
viene introdotto utilizzando la direttiva nello spazio dei nomi globali.
Soluzione
Mentre si utilizza il namespace n sta tirando il nome n :: A nello spazio dei nomi globali, non dichiara che A nello spazio dei nomi globali.Quindi un ulteriore A nello spazio dei nomi globali è l'amico di B. Clang è sbagliato.
Altri suggerimenti
Per rendere N::A
senza qualificazione A friend
di B
che usi
friend A;
.
piuttosto che
friend class A;
.
Quando si utilizza un specificatore di tipo elaborato, I.e., class A
, ed è in questo modulo specifico, introduce un nome di classe (vedere 3.4.4 [BASIC.Lookup.eLab] Paragrafo 2).