2011-12-24 6 views
37

C11 soporta estructuras anónimas, así:¿Por qué C++ 11 no admite estructuras anónimas, mientras que C11 sí?

struct Foo 
{ 
    struct 
    { 
     size_t x, y; 
    }; 
}; 
struct Foo f; 
f.x = 17; 
f.y = 42; 

Básicamente, los miembros de dicha una struct se tratan como si fueran miembros de la encierra struct o union (de forma recursiva, si la estructura de cerramiento era en sí misma anónimo).

¿Cuál fue la razón de ser de C++ 11 que no incluía también estructuras anónimas? No son muy útiles (sobre todo dentro de uniones, para eliminar el tipeo de un identificador para el struct). Pero parecen una adición suficientemente obvia a la especificación (y una ya implementada por muchos compiladores) que seguramente se debieron haber discutido, al menos para preservar la compatibilidad con el estándar C11. Entonces, ¿por qué no fueron agregados?

+12

No estoy de acuerdo con el voto en que esta pregunta no sea constructiva. Las preguntas más suaves también están bien. – GManNickG

+6

__Prácticamente hablando, la mayoría de los compiladores de C++ 11 también admiten estructuras anónimas. Los he usado tanto en MSVC++ (desde siempre) como en el compilador llvm C++ 11 de Apple. – bobobobo

+0

MinGW también admite estructuras/uniones anónimas. –

Respuesta

42

Se han realizado pocos esfuerzos para mantener la compatibilidad entre C++ y C a medida que los dos idiomas evolucionan. Tenga en cuenta que las matrices de pila de longitud variable han estado en C desde 1999, pero no se incluyeron en C++ 11. Si bien generalmente no introducen cosas que se contradicen entre sí, el comité de C++ no está haciendo todo lo posible para asegurarse de que C++ 11 sea compatible con las versiones de C más allá de C89.

Además, esta característica sería bastante compleja en C++, porque un struct no es más que un class. Y una estructura/clase anónima debería tener todas las características de una estructura/clase regular, ¿sí? De lo contrario, ¿de qué sirve tenerlo?

¿Qué significaría construir un anónimo struct? ¿Cómo definirías el constructor? Algo tan simple como:

struct Foo 
{ 
    struct 
    { 
     size_t &x; 
    }; 
}; 

simplemente no es posible porque el interior struct tiene ningún constructor. Y no hay forma de especificar uno. Un struct no puede construir los miembros de otro struct dentro de él.

Para algo como esto:

struct Foo 
{ 
    size_t outer; 
    struct 
    { 
     void SomeFunc(); 
     size_t x; 
    }; 
}; 

Lo this puntero no SomeFunc conseguir? ¿Cuál sería el tipo de this, el tipo sin nombre y sin nombre? ¿Cómo definirías SomeFunc fuera de la estructura? El nombre de SomeFunc no puede ser Foo::SomeFunc, porque SomeFunc vive en un ámbito interno.

Es demasiado complejo para tratar con C++. Y ciertamente no vale la pena preocuparse por agregar esa complejidad para.

+14

Esto tiene sentido razonable, aunque puedo imaginar restricciones que lo harían completamente sensato: POD, sin métodos (heredados o no), y completamente público, creo, resuelva los problemas que plantea. También me parece que los sindicatos anónimos ya presentan muchos de estos problemas, por lo que los problemas no parecen "demasiado complejos" para mí, excepto en el sentido de que hay demasiado poco para resolverlos. –

+11

"¿Qué significaría construir una estructura sin nombre? ¿Cómo definirías el constructor?". Lo mismo se puede pedir para una unión sin nombre. Los sindicatos también pueden tener constructores. –

+0

Además, la mayor parte de lo que obtienes en C11 de estructuras anónimas también puedes obtener de la herencia. Las uniones anónimas serían más útiles, pero como Nicol señala, la característica completa no es adecuada para C++. –

3

Para jugar a la defensa del diablo: las declaraciones de clase y estructura se usan a menudo para envolver las declaraciones de tipo específicas de clase.

typedef struct { 

} name; 

por lo tanto debe ser permitido.

Por lo tanto

struct { 

} 

debería ser así.

Sin embargo, si consideramos esto como una declaración dentro del espacio de nombres interno de una clase, no habría forma de acceder al interior de la estructura.

Dado que struct! = Namespace en C, C puede crear reglas como el acceso a una estructura anónima a través de la estructura circundante.

Para que C++ lo permita, necesitaría un caso especial en esta situación, lo que complicaría la resolución del nombre.

Por supuesto, jugar al abogado del diablo del diablo - C en realidad lo hizo. Agregó un nivel extra para la resolución de nombres: si no puede encontrar el nombre en un enlace, verifique los miembros anónimos de la estructura. Lo cual es un poco mágico, de una manera que puedo ver a los miembros del comité de C++ como molestos.

También plantea preguntas: si se puede acceder a una estructura anónima a través de su clase principal, qué ocurre con las estructuras anónimas en un espacio de nombres.

Por supuesto, si realmente quieres saber, solo pregúntale a Stroustrup: responde a los correos electrónicos.

+0

Esta no puede ser la razón correcta --- las uniones * anónimas * son * compatibles (¡incluso en C++ 98!), ¿Pero las estructuras anónimas no? Si este fuera el motivo, tampoco deberían respaldarse las uniones anónimas, ya que comparten el mismo espacio de nombres que las estructuras. –

+0

Encuentro divertido el "pequeño mágico". Para mí se parece más a "Esto no es C. Decidimos. Neener-neener". – 6502

+0

C++ ya admite uniones anónimas y espacios de nombres anónimos donde los contenidos se derraman, como si estuvieran declarados en línea en el ámbito externo. Las estructuras anónimas completan ese trío (particularmente útil en la programación de gráficos). En otro aspecto, C++ 11 incluso va más allá de C y admite espacios de nombres en línea (incluso cuando se nombra, no solo anónimo). http://stackoverflow.com/questions/11016220/what-are-inline-namespaces-for –

-2

Se piensa que esto funciona en C++ 11

struct A 
{ 
    int someVariable; 
}; 

struct B : public A 
{ 
    int someOtherVariable; 
}; 

Se usa como:

B structB; 
structB.someVariable = 5; 
structB.someOtherVariable = 6; 

Esto me ayudó a resolver un problema similar.

Cuestiones relacionadas