Pregunta

¿Alguien sabe por qué typedefs de nombres de clases no funcionan como nombres de clase para la declaración amigo?

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
};
¿Fue útil?

Solución

No puede, actualmente. No sé la razón todavía (sólo mirar hacia arriba, porque me parece interesante). Actualización: se puede encontrar la razón en la primera propuesta para apoyar typedef-nombres como amigos: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1520.pdf . La razón es que la norma sólo se admite de tipo especificadores elaborados. Es fácil permitir que sólo aquellos, y decir si la entidad declarada como amigo no se declara sin embargo, se hizo un miembro del espacio de nombres de los alrededores. Pero esto significa que si usted desea utilizar un parámetro de plantilla, que tendría que hacer (se requiere una clase a continuación, por ejemplo)

friend class T;

Pero eso trajo problemas adicionales, y fue figurado no vale la pena la ganancia. Ahora, el documento propone para permitir especificadores de tipo adicionales para dar (de modo que esto, entonces permite el uso de los parámetros de plantilla y typedef-nombres).

El siguiente ++ versión C (debido a 2010) será capaz de hacerlo.

Vea esta propuesta actualizada de la norma: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf . No sólo permitirá typedef nombres, sino también los parámetros de plantilla que se utiliza como el tipo declarado como amigo.

Otros consejos

AFAIK, en C ++ typedef no crea un sinónimos de pleno derecho cuando se utiliza en conjunción con las clases. En otras palabras, no es como una macro.

Entre las restricciones es que el sinónimo no puede aparecer después de una clase o estructura prefijo, o ser utilizado como un nombre destructor o constructor. Tampoco se puede subclase el sinónimo. Yo apostaría que también se quiere decir que no pueda amigo a él.

He intentado en el VC ++ 8.0 el código:

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

Se compila sin errores.

No estoy al tanto si MS específica o no.

A typedef define un tipo. Amigo decls declarar clases o funciones (alcances sustancialmente) amigo, que a su vez tiene "acceso" a la zona no pública de la clase que se declara ...

Primitives, es decir, un flotador o un int * no definen un ámbito con código, etc., que no "utilizan" la clase de todos modos.

No se olvide, también puede "paquete" convenciones de llamada, attribs de alineación y cosas específicas otra compilador en un typedef, es decir, varios tipos de vectores implementados por la misma clase pero con attribs alineación distintas. => Un tipo no es una clase, pero viceversa.

mi humilde opinión, se declara un amigo typedef puede ser útil, pero cuando "typedefs de clase" desde cualquier lugar se pueden establecer como amigo, las amistades puede llegar a ser extremadamente incomprensible y por lo tanto propenso a errores, especialmente donde las plantillas se utilizan en exceso.

Anulación de un solo desastre typedef lata hasta la totalidad del proyecto debido a las dependencias generalizadas. amigos de plantilla y los typedefs plantilla 0x son útiles, pero no se relajan las reglas de una declaración amigo.

No sé a cualquier propuesta relativa typedefs amigo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top