Question

Est-ce que quelqu'un sait pourquoi typedefs des noms de classe ne fonctionnent pas comme les noms de classe pour la déclaration d'ami?

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
};
Était-ce utile?

La solution

Il ne peut pas, actuellement. Je ne sais pas encore la raison (juste regarder vers le haut, parce que je trouve intéressant). Mise à jour: vous pouvez trouver la raison dans la première proposition visant à appuyer les noms de typedef-comme des amis: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1520.pdf . La raison est que la norme uniquement prise en charge de type-spécificateurs élaborés. Il est facile de permettre que ceux-ci, et dire si l'entité déclarée comme ami n'est pas encore déclaré, il sera membre de l'espace de noms environnant. Mais cela signifie que si vous souhaitez utiliser un paramètre de modèle, vous devez faire (une classe est nécessaire, par exemple)

friend class T;

Mais qui a amené des problèmes supplémentaires, et il a été figurés ne vaut pas le gain. Maintenant, le document propose de permettre spécificateurs supplémentaires à donner (de sorte que cela permet alors l'utilisation de paramètres de modèle et les noms de typedef-).

La prochaine version C ++ (en raison de 2010) sera en mesure de le faire.

Voir cette proposition mise à jour à la norme: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf . Il ne permettra pas que typedef noms, mais aussi des paramètres modèle à utiliser comme type déclaré comme ami.

Autres conseils

AFAIK, en C ++ typedef ne crée pas des synonymes à part entière lorsqu'ils sont utilisés conjointement avec les classes. En d'autres termes, il est pas comme une macro.

Parmi les restrictions est que le synonyme ne peut pas apparaître après un préfixe de classe ou struct, ou être utilisé comme un nom de destructor ou le constructeur. Vous pouvez également ne pas sous-classe synonyme. Je serais prêt à parier que est signifie également que vous ne pouvez pas ami il.

J'ai essayé dans 8.0 le code du VC:

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

Il est compilé sans erreurs.

Je ne sais pas si elle MS spécifique ou non.

A typedef définit un type. Ami decls déclarer des classes d'amis ou des fonctions (scopes essentiellement), qui ont ensuite « accès » à la zone non publique de la classe en déclarant ...

Primitives, i.e. un flotteur ou un int * ne définissent pas un champ d'application avec le code etc., ils ne sont pas « utiliser » la classe de toute façon.

Ne pas oublier, vous pouvez aussi « pack » conventions d'appel, attribs d'alignement et d'autres compilateur choses spécifiques dans un typedef, à savoir de multiples types de vecteurs mis en œuvre par la même classe, mais avec attribs d'alignement distincts. => Un type est pas une classe, mais vice-versa.

à mon humble avis, déclarant un ami typedef peut être utile, mais quand « typedefs de classe » de partout peuvent être définis comme ami, les amitiés peuvent devenir extrêmement incompréhensible et donc sujette aux erreurs, en particulier lorsque les modèles sont utilisés de manière excessive.

Invalidation un seul typedef peut gâcher l'ensemble du projet en raison de dépendances généralisées. amis et les modèles typedefs modèles 0x sont utiles, mais ne se détendent pas les règles d'une déclaration d'ami.

Je ne sais pas de toute proposition concernant typedefs ami.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top