2009-03-18 8 views
22

El compilador g ++ se queja con este error cuando se declaro un amigo de esta manera:una clave de clase debe ser declarado cuando se declara un amigo

friend MyClass; 

en lugar de

friend class MyClass; 

¿Por qué la clase palabra clave se requiere? (el compilador de Borland C++, BTW, no lo requiere).

¿No pudo el compilador simplemente buscar MyClass en la tabla de símbolos y decir que se declaró como una clase? (Obviamente está haciendo la búsqueda de todos modos porque se queja cuando MyClass no se ha declarado)

No es como si estuviera haciendo una declaración directa de la clase: todavía tengo que haber declarado la clase anterior o al menos lo han declarado adelante.

No tendría sentido para mí (en realidad sería grande) si

friend class MyClass; 

hace una declaración hacia adelante si es necesario, de lo contrario sólo parece que la sal sintáctica para mí.

He estado usando alegremente amigo declaraciones sin la palabra clave clase o estructura con ninguna queja del compilador desde hace casi 20 años. ¿Es esto algo bastante nuevo?

+1

20 años! Debes haber estado trabajando con Bjorn. –

+0

Utilicé C-Front cuando estaba en la escuela de posgrado alrededor de 1989. He usado principalmente Borland C++ desde 1991. –

+3

@Martin: Bjorn ?! Lol. –

Respuesta

22

Me sorprendió sobre esto (y como resultado eliminado una respuesta incorrecta anterior). El estándar C++ 03 dice en 11.4:

Se debe usar un especificador de tipo elaborado en una declaración de amigo para una clase.

cuando para asegurarse de que no hay malentendidos, notas al pie que con: Se requiere que la llave de la clase de tipo especificador elaborado

.

GCC es el único compilador que tengo de que se queja de la falta-clave de clase, pero parece que otros compiladores están dejando que nos alejamos con algo no estándar ...

Ahora en cuanto a la Justificación: tendría que preguntarle a alguien que sabe más sobre compiladores (o estándares) que yo.

+2

' friend' without class-key funciona bajo g ++ 4.7.0/4.7.3 con opción '-std = C++ 11' – Interarticle

+0

Sería mejor Si actualiza su respuesta de acuerdo con C++ 11 también, C++ 11 ha introducido __extended friend declarations__. Consulte https://www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/introduction_to_the_c_11_feature_extended_declaration_declaration3?lang=en – Destructor

22

Al punto de su pregunta, porque es la forma en que ISO/IEC 14882: 2003 lo especifica (sección 7.1.4). El constructo friend se especifica esencialmente como:

friend <declaration> 

donde <declaration> es la declaración válida de una clase, estructura, plantilla, o función.

Por lo tanto,

MyClass; 

no es una declaración válida, mientras que:

class MyClass; 

o:

struct MyClass; 

son.

Idem para, correspondientemente:

friend class MyClass; 

o

friend struct MyClass; 
+0

Gracias por esto, ustedes salvan mi tocino hoy. – Rokujolady

+0

Buena respuesta, GCC rocks :) – ierax

+0

Y si 'MyClass' es una plantilla de clase, la declaración' friend' también requiere 'template' –

Cuestiones relacionadas