Supongamos que tengo una clase F
que debería ser amiga de las clases G
(en el espacio de nombres global) y C
(en el espacio de nombres A
).¿Por qué una clase de amigo de C++ necesita una declaración directa solo en otros espacios de nombres?
- ser amigo de
A::C
,F
debe ser declarada hacia adelante. - para ser amigo de
G
, no es necesaria la declaración directa deF
. - del mismo modo, una clase
A::BF
puede ser amigo deA::C
sin declaración hacia adelante
El código siguiente ilustra este y compila con GCC 4.5, VC++ otras 10 y al menos con un compilador.
class G {
friend class F;
int g;
};
// without this forward declaration, F can't be friend to A::C
class F;
namespace A {
class C {
friend class ::F;
friend class BF;
int c;
};
class BF {
public:
BF() { c.c = 2; }
private:
C c;
};
} // namespace A
class F {
public:
F() { g.g = 3; c.c = 2; }
private:
G g;
A::C c;
};
int main()
{
F f;
}
Para mí esto parece inconsistente. ¿Hay alguna razón para esto o solo es una decisión de diseño del estándar?
+1 para la referencia estándar real. –
Una persona razonable podría preguntar por qué no es suficiente escribir "' friend class :: F; '" (como se muestra en el código del OP), así explícitamente presionando 'F' en el espacio de nombres global. Creo que la respuesta es la siguiente: "un id calificado nunca declara un nombre nuevo", pero no estoy seguro de lo que dice el estándar en este punto. – zwol
@Zack Esa fue mi pregunta inicial, también: ¿Por qué tengo que agregar una declaración directa, cuando muevo una clase en otro espacio de nombres? Pero ya hay un par de discusiones sobre este tema (por ejemplo, http://stackoverflow.com/questions/2059665/, http://stackoverflow.com/questions/1368642/). Parece que no necesitar una declaración directa en el mismo ámbito es una conveniencia que ha sido otorgada por los autores del estándar. – pesche