2011-03-05 12 views
5

Después de investigar un poco, descubrí que C++ 0x almacena los elementos en una tupla hacia atrás en la memoria.C++ 0x Tuplas Almacenar elementos al revés

Por ejemplo, tome este código:

std::tuple<char, char, char> x('\0', 'b 'a'); 
char* y = (char*)&x; 
std::cout << sizeof(x) << std::endl; 
std::cout << y << std::endl;

cuando se compila con GCC 4.5.2, me sale el siguiente resultado:

3 
ab

Este principio me desconcertó. ¿Por qué los datos están almacenados al revés? Después de caza a través de cabeceras sin querer ofuscado de GNU, me di cuenta de que la aplicación fue similar a esto:

template<typename head, typename... tail> class tuple<head, tail...> : public tuple<tail...> 
{ 
    head value; 
    ... 
};

Debido a que la clase base contiene el último elemento, a continuación, la siguiente clase derivada contiene el penúltimo, etc., el actual El orden de los argumentos de la plantilla se invierte.

Cuando entré por primera vez en tuplas, pensé que podría usarlos para una función como glInterleavedArrays(), que establece una matriz de datos de vértice como tuplas de colores, coordenadas de textura, normales y puntos. Por supuesto, si hago una serie de tuplas, estos datos deberán ingresarse en orden inverso, lo que puede dar lugar a errores realmente extraños si olvida colocar los argumentos en el orden correcto.

¿Qué tal algo así, entonces?

template<typename... head, typename tail> class tuple<head..., tail> : public tuple<head...> 
{ 
    tail value; 
    ... 
};

Bajo el GCC 4.5.2:

error: parameter pack argument ‘head ...’ must be at the end of the template argument list

A menos que estos estén disponibles en el futuro, estoy bastante atascado en encontrar otra forma de implementar esto. ¿Hay otra manera? ¿Alguna manera de engañar al CCG para que consiga una tupla ordenada correctamente en cuanto a la memoria?

Respuesta

5

El diseño de tupla que está explorando es un detalle de implementación no especificado de tuple. Otras implementaciones tendrán otros diseños. Si escribe en este, dependiendo del diseño de gcc, su código puede no ser portátil para otras std :: libs.

La implementación de tupla libc++ (por ejemplo) tiene el diseño opuesto (en orden).

5

¿Por qué te importa cuál es la implementación de la tupla? Program to an interface, not an implementation.

Si solo utiliza tuple a través de su interfaz anunciada, obtendrá sus objetos en el mismo orden en que los ingresó. Si en cambio rompe la encapsulación accediendo directamente a sus contenidos, por ejemplo, mediante el puntero poco fiable de su Por ejemplo, todas las apuestas están apagadas.

+0

Ya dije por qué - 'glInterleavedArrays()' es una función que solicita una matriz de datos intercalados. Mi intención era crear una clase de tupla que operara según este principio, intercalando datos en una matriz de tuplas para poder pasar los datos a GL. Si desea obtener más información, consulte la documentación de OpenGL: http://www.opengl.org/sdk/docs/man/xhtml/glInterleavedArrays.xml –

+0

@RetroX: entonces, en lugar de confiar en la implementación de tuple, quiere un objeto cuya interfaz proporciona un medio de serialización en un orden conocido. De cualquier manera, desea que la interfaz proporcione la garantía, para que no esté atado a los detalles de implementación. –