Por que não pode declarar um amigo através de um typedef?
-
23-08-2019 - |
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
};
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.