Pergunta

Alguém sabe por que typedefs de nomes de classes não funcionam como nomes de classe para o amigo declaração?

class A
{
public:
};

class B : public A
{
public:
   typedef A SUPERCLASS;
};

typedef A X;

class C
{
public:
   friend class A;             // OK
   friend class X;             // fails
   friend class B::SUPERCLASS; // fails
};
Foi útil?

Solução

Não pode, atualmente. Eu não sei a razão ainda (apenas olhando-o, porque acho que é interessante). Update: você pode encontrar a razão da primeira proposta de apoio typedef nomes como amigos: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1520.pdf . A razão é que o padrão suportado apenas elaborados-type-especificadores. É fácil para permitir que apenas aqueles, e dizer se a entidade declarada como amigo ainda não é declarada, será feito um membro do namespace circundante. Mas isso significa que se você quiser usar um parâmetro de modelo, você teria que fazer (uma classe é necessária, então, por exemplo)

friend class T;

Mas isso trouxe problemas adicionais, e foi figurado não vale a pena o ganho. Agora, o documento propõe a permitir que especificadores de tipo adicionais para ser dado (de modo que este, em seguida, permite o uso de parâmetros do modelo e typedef nomes).

A próxima versão C ++ (devido a 2010) será capaz de fazê-lo.

Veja esta proposta atualizada para o padrão: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf . Não vai permitir que apenas typedef nomes, mas também parâmetros de modelo a ser usado como o tipo declarado como amigo.

Outras dicas

AFAIK, Em C ++ typedef não cria um sinônimos de pleno direito quando usado em conjunto com classes. Em outras palavras, não é como uma macro.

Entre as restrições é que o sinônimo não pode aparecer após uma classe ou struct prefixo, ou ser usado como um nome destructor ou construtor. Você também não pode subclasse o sinônimo. Eu apostaria que é também significa que você não pode amigo-lo.

Eu tentei no VC ++ 8.0 o código:

...
class C
{
public:
  friend class A;       
  friend X;             
  friend B::SUPERCLASS; 
};
...

Ele é compilado sem erros.

Não tenho conhecimento se ele MS específica ou não.

A typedef define um tipo. Amigo decls declarar classes amigo ou funções (substancialmente escopos), que, em seguida, ter "acesso" para a área não pública da classe declarando ...

Primitives, ou seja, um flutuador ou um int * não definir um alcance com código etc, eles não "use" o de qualquer maneira classe.

Não se esqueça, você também pode "embalar" convenções de chamada, attribs alinhamento e outras coisas compilador específico em um typedef, ou seja, vários tipos de vetor implementadas pela mesma classe, mas com attribs alinhamento distintas. => Um tipo não é uma classe, mas vice-versa.

IMHO, declarando um amigo typedef pode ser útil, mas quando "typedefs classe" de qualquer lugar pode ser definido como amigo, a amizade pode se tornar extremamente incompreensível e, portanto, propenso a erros, especialmente onde os modelos são usados ??excessivamente.

A invalidação de um único typedef pode atrapalhar todo o projeto devido a dependências generalizadas. amigos modelo e os 0x typedefs modelo são úteis, mas não relaxar as regras de uma declaração amigo.

Eu não sei de qualquer proposta relativa typedefs amigo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top