As classs internas do C ++ são automaticamente amigas?

Se eu definir uma class interna em C ++, será automaticamente um amigo da class que a contém? Por exemplo, isso é legal:

class Outer { public: class Inner { public: void mutateOuter(Outer& o); }; private: int value; }; void Outer::Inner::mutateOuter(Outer& o) { o.value ++; // Legal? Or not? } 

Eu pergunto porque em alguns compiladores que eu tentei (VS2003) este código não funciona, mas eu ouvi pelo menos informalmente que ele funciona em alguns compiladores. Não consigo encontrar uma seção relevante na especificação do C ++ sobre isso, e se alguém puder citar algo específico que diria que é ou não legal, seria ótimo.

Depois de ter perguntado mais ou menos a mesma pergunta aqui , eu queria compartilhar a resposta (aparentemente) atualizada para o C ++ 11:

Citado em https://stackoverflow.com/a/14759027/1984137 :

padrão $ 11.7.1

“Uma class aninhada é um membro e, como tal, tem os mesmos direitos de access que qualquer outro membro. Os membros de uma class envolvente não têm access especial aos membros de uma class aninhada; as regras de access habituais devem ser obedecidas”

e as regras de access habituais especificam que:

“Um membro de uma class também pode acessar todos os nomes aos quais a class tem access …”

exemplos específicos foram dados no padrão:

 class E { int x; class B { }; class I { B b; // OK: E::I can access E::B int y; void f(E* p, int i) { p->x = i; // OK: E::I can access E::x } }; } 

Até C ++ 11 (ie C ++ 98 e C ++ 03)

Em C ++ 98 e C ++ 03, a class aninhada não pode acessar membros private e protected da class de inclusão por padrão.

O C ++ Standard (2003) diz em $ 11,8 / 1 [class.access.nest],

Os membros de uma class aninhada não têm access especial aos membros de uma class de inclusão , nem a classs ou funções que concederam amizade a uma class envolvente; as regras de access habituais (cláusula 11) devem ser obedecidas. Os membros de uma class envolvente não têm access especial aos membros de uma class aninhada; as regras de access habituais (cláusula 11) devem ser obedecidas.

Exemplo do próprio padrão:

 class E { int x; class B { }; class I { B b; // error: E::B is private int y; void f(E* p, int i) { p->x = i; // error: E::x is private } }; int g(I* p) { return p->y; // error: I::y is private } }; 

Desde C ++ 11

A restrição acima foi removida desde C ++ 11. Agora as classs aninhadas podem acessar os membros private e protected da class envolvente:

 class E { int x; class B { }; class I { B b; // ok: even though E::B is private int y; void f(E* p, int i) { p->x = i; // ok: even though E::x is private } }; int g(I* p) { return p->y; // ok: even though I::y is private } }; 

Espero que ajude.

Como o questionador parece ter aceitado uma das respostas, isso é apenas uma suplementação.
O padrão parece ter mudado a especificação sobre a acessibilidade.

§11.8 / 1 em C ++ 98 afirma:

Os membros de uma class aninhada não têm access especial aos membros de uma class de inclusão, nem a classs ou funções que concederam amizade a uma class envolvente; as regras habituais de access devem ser obedecidas.

§11.8 / 1 em N1804 (após TR1) afirma:

Uma class aninhada é um membro e, como tal, tem os mesmos direitos de access que qualquer outro membro.

Eu acho que os compiladores C ++ atuais obedecem a novas especificações.

Essa resposta está relacionada à especificação (desatualizada) do C ++ 03. A resposta aceita nesta questão é mais atualizada.

Bem, eu me sinto bobo por fazer essa pergunta agora porque acabei de encontrar a parte relevante da especificação que cobre isso: §11.8 / 1:

Os membros de uma class aninhada não têm access especial aos membros de uma class de inclusão, nem a classs ou funções que concederam amizade a uma class envolvente; as regras de access habituais (cláusula 11) devem ser obedecidas. Os membros de uma class envolvente não têm access especial aos membros de uma class aninhada; as regras habituais de access (cláusula 11) devem ser obedecidas

(Minha ênfase)

Portanto, parece que não, as classs internas não têm privilégios de access especiais.

Eu não tenho a localização precisa do topo da minha cabeça, mas lembro-me de ler as especificações e descobrir que quaisquer dados privados em uma class estão escondidos de todas as outras classs, incluindo classs aninhadas.

Basicamente, o aninhamento de uma class define um determinado escopo e não acessa privilégios.

Intereting Posts