lenguaje - estructuras dev c++
¿Por qué C++ no permite estructuras anónimas? (6)
Algunos compiladores de C ++ permiten uniones y uniones anónimas como una extensión de C ++ estándar. Es un poco de azúcar sintáctico que ocasionalmente es muy útil.
¿Cuál es la razón que impide que esto sea parte del estándar? ¿Hay un bloqueo técnico? ¿Uno filosófico? ¿O simplemente no es suficiente la necesidad de justificarlo?
Aquí hay una muestra de lo que estoy hablando:
struct vector3 {
union {
struct {
float x;
float y;
float z;
};
float v[3];
};
};
Mi compilador aceptará esto, pero advierte que "struct / union sin nombre" es una extensión no estándar de C ++ .
Basándome en la edición, los comentarios y este artículo de MSDN: Estructuras anónimas , me arriesgaré a suponer que encaja mal con el concepto de encapsulación. No esperaría que un miembro de una clase se metiera con el espacio de nombres de mi clase más allá de simplemente agregar un miembro. Además, los cambios en la estructura anónima pueden afectar mi clase sin permiso.
Como otros han señalado, las uniones anónimas están permitidas en C ++ estándar, pero las estructuras anónimas no lo son.
La razón de esto es que C admite uniones anónimas pero no estructuras anónimas *, por lo que C ++ admite la compatibilidad pero no la última porque no es necesaria para la compatibilidad.
Además, no hay mucho uso para las estructuras anónimas en C ++. El uso que demuestras, para tener una estructura que contiene tres flotantes a los que se puede hacer referencia por .v[i]
, o .x
, .y
y .z
, creo que da como resultado un comportamiento indefinido en C ++. C ++ no le permite escribir a un miembro de una unión, digamos .v[1]
, y luego leer de otro miembro, digamos .y
. Aunque el código que hace esto no es raro, en realidad no está bien definido.
Las instalaciones de C ++ para tipos definidos por el usuario brindan soluciones alternativas. Por ejemplo:
struct vector3 {
float v[3];
float &operator[] (int i) { return v[i]; }
float &x() { return v[0]; }
float &y() { return v[1]; }
float &z() { return v[2]; }
};
* C11 aparentemente agrega estructuras anónimas, por lo que una futura revisión de C ++ puede agregarlas.
Diré, puedes limpiar tu declaración vector3
simplemente usando un union
union vector3 {
struct { float x, y, z; } ;
float v[3] ;
} ;
Claro, las estructuras anónimas eran una extensión de MSVC . Pero ISO C11 lo permite ahora, y gcc lo permite , y también lo hace el compilador llvm de Apple.
¿Por qué en C11 y no en C ++ 11? No estoy seguro, pero prácticamente la mayoría (compiladores C ++ de gcc ++, MSVC ++ y compilador C ++ de Apple) los admiten.
Los sindicatos pueden ser anónimos; ver el Estándar, 9.5 párrafo 2.
¿Qué propósito considera que cumple una estructura o clase anónima? Antes de especular sobre por qué algo no está en el Estándar, me gustaría tener una idea de por qué debería ser así, y no veo el uso para una estructura anónima.
No estoy seguro de lo que quieres decir. Sección 9.5 de la especificación C ++, cláusula 2:
Una unión de la forma
union { member-specification } ;
se llama una unión anónima; define un objeto sin nombre de tipo sin nombre.
Usted puede hacer cosas como esta también:
void foo()
{
typedef
struct { // unnamed, is that what you mean by anonymous?
int a;
char b;
} MyStructType; // this is more of a "C" style, but valid C++ nonetheless
struct { // an anonymous struct, not even typedef''d
double x;
double y;
} point = { 1.0, 3.4 };
}
No siempre es muy útil ... aunque a veces es útil en desagradables definiciones macro.
Tu codigo
union {
struct {
float x;
float y;
float z;
};
float v[3];
};
es como
union Foo {
int;
float v[3];
};
que seguramente no es válido (en C99 y antes).
La razón probablemente sea para simplificar el análisis sintáctico (en C), porque en ese caso solo necesita verificar que el cuerpo struct / union solo tenga "declaraciones de declaradores" como
Type field;
Dicho esto, gcc y "otros compiladores" admiten campos sin nombre como una extensión.
Editar: las estructuras anónimas ahora se admiten oficialmente en C11 (§6.7.2.1 / 13).