2010-07-09 7 views
7

Sigo buscando, pero parece que no hay interés por parte de los desarrolladores de compiladores en apoyar esto.¿Es probable que algún compilador mainstream soporte C++ 0x unrestricted unions en el futuro cercano?

Para mí, parece extraño: básicamente, el C++ actual tiene restricciones sobre uniones que siempre fueron irritantes y nunca apropiadas. Uno pensaría que, básicamente, eliminar algunas comprobaciones de errores sería una forma relativamente simple de marcar una casilla adicional de soporte de C++ 0x, pero los desarrolladores de compiladores AFAICT todavía no lo han hecho.

Por qué estoy interesado es porque proporciona una solución simple a un problema recurrente en la codificación de la estructura de datos: cómo reservar memoria para una instancia de tipo desconocido (parámetro de plantilla), preferiblemente con tanta seguridad como sea posible en las circunstancias, pero sin invocar a ningún constructor que esté definido en ese tipo. El punto realmente importante es que se deben seguir las reglas de alineación.

Una unión no restringida es perfecta para esto: le da un tipo que no tiene constructores o destructores, pero que tiene el tamaño y la alineación correctos para permitir a cualquier miembro. Por supuesto, existen formas de construir y destruir explícitamente cuando sea necesario, y cuando necesite un acceso de tipo seguro, solo debe usar el miembro de la unión correspondiente para acceder a él. Apoyo a los sindicatos "adecuados" puede ser útil también, pero se obtiene enormes beneficios incluso para una unión de un solo miembro, como ...

union Memory_For_Item_t 
{ 
    Item_t m_Item; 
}; 

Incluso con las características estandarizadas de manipulación de la alineación en C++ 0x, este enfoque gana por conveniencia y seguridad cuando, por ejemplo desea espacio para x elementos en un nodo, no todos los cuales estarán en uso (o construidos) en cualquier momento. Sin C++ 0x, todavía estamos en el tema de la alineación WRT de edades oscuras: cada compilador lo hace de forma no estándar.

El único problema con las uniones sin restricciones: no hay soporte para ellas que pueda encontrar.

Respuesta

4

¿Futuro próximo? No contaría con eso. Como http://wiki.apache.org/stdcxx/C%2B%2B0xCompilerSupport presenta bien, ninguno de los compiladores actuales lo admite aunque se están implementando muchas características de C++ 0x.

Sin embargo, como explica N2544:

El trabajo en torno a las limitaciones actuales del sindicato es la creación de una unión falsa utilizando la programación plantilla o yesos.

Por lo tanto, la situación que está describiendo probablemente ya tiene una solución, aunque un poco desordenada.

+0

Sí, tengo un enfoque de plantilla ahora, pero depende de los condicionales del preprocesador para identificar compiladores y otras maldades, principalmente para lograr el correcto alineamiento. IOW es frágil y generalmente desagradable, y cuanto antes pueda reemplazarlo, mejor. – Steve314

+0

Hmmm - tabla iterante, pero de solo tres filas completamente en blanco, una solo tiene que ser para la característica que estoy esperando. Ah, bueno, las expresiones y cierres de lamda serán agradables, supongo. – Steve314

1

Sí - Tengo un enfoque plantilla ahora, pero depende de preprocesador condicionales para identificar los compiladores y otra maldad, sobre todo para conseguir la alineación manejo correcto. OIA es quebradizo y generalmente desagradable

¿Por qué no sólo tiene que utilizar boost::variant? si no va a utilizar boost y ya está usando C++ 0x, utilice características de tipo como std::alignment_of/std::aligned_storage, que sean estandarizadas y multiplataforma, y ​​si su compilador las admite ahora, puede usar plantillas variadic. Use la metaprogramación de plantillas para calcular el tipo más grande en la lista de tipos, etc.

+0

Mi plantilla es anterior a boost :: variant por bastante. Reemplazar todos los usos con alguna función de refuerzo o característica C++ 0x que no es ideal, solo para reemplazarlo más tarde, es un poco inútil. No estoy usando C++ 0x para nada, solo espero poder utilizar una característica en particular. Finalmente, "usar boost" no es realmente la solución instantánea mágica que crees que es: otro problema de dependencia de compilación, etc. Si tuviese un valor a largo plazo, entonces está bien, pero tal como están las cosas, seguiré haciendo lo que sea Lo estoy haciendo hasta que aparezca la unión no restringida. – Steve314

+0

@ Steve314 no tiene sentido, realmente depende de para qué uses los sindicatos, si vas a usarlo como un tipo de datos algebraico también conocido como unión discriminada/etiquetada, entonces no es inútil en absoluto porque es un raw (generalizado)) unión no es útil para trabajar como es. Las cosas como boost :: variant son igualmente útiles en C++ 0x, independientemente de las uniones generalizadas o no. –

+0

@ Steve314 "Estoy buscando una manera de reservar la memoria para un tipo particular sin invocar constructores, etc." No necesita una unión para eso, lo que quiere es ** nuevo operador de ** ubicación ** que es solo usado para la construcción y llamando explícitamente al destructor en el momento correcto. Si está administrando la memoria no inicializada, debe tener cuidado con los problemas de alineación y es por eso que puede usar rasgos de tipo, aumentar los rasgos de tipo para determinar la alineación y generar tipos de almacenamiento alineados en tiempo de compilación, es multiplataforma, de hecho así es como boost :: variant funciona debajo. –

3

GCC ahora lo enumera como compatible con version 4.6. Parece que se introdujo el 14 de julio, con this patch. El futuro es ahora.

+0

como, woah ... amigo. –

Cuestiones relacionadas