2009-07-04 14 views
10

¿Cuál es el uso básico de std :: tr1 :: aligned_storage? ¿Se puede usar como memoria automática para un tipo de datos Foo como el siguiente?¿cuál es el uso básico de alignment_storage?

struct Foo{...}; 
    std::tr1::aligned_storage<sizeof(Foo) 
     ,std::tr1::alignment_of<Foo>::value >::type buf; 
    Foo* f = new (reinterpret_cast<void*>(&buf)) Foo(); 
    f->~Foo(); 

Si es así, ¿qué pasa con el almacenamiento de múltiples Foo en el buf como,

std::tr1::aligned_storage<5*sizeof(Foo) 
      ,std::tr1::alignment_of<Foo>::value >::type buf; 
    Foo* p = reinterpret_cast<Foo*>(&buf); 
    for(int i = 0; i!= 5; ++i,++p) 
    { 
     Foo* f = new (p) Foo(); 
    } 

¿Son válidos los programas? ¿Hay algún otro caso de uso para eso? La búsqueda en Google solo arroja la documentación sobre alignment_storage, pero muy poco sobre el uso de la misma.

Respuesta

9

Bueno, aparte de su uso de reinterpret_cast, me parece bien. (No estoy 100% seguro en el segundo).

El problema con reinterpret_cast es que no garantiza el resultado del molde, solo que si devuelve el resultado al tipo original, obtiene el valor original. Por lo tanto, no hay garantía de que el resultado del lanzamiento contenga el mismo patrón de bits, o apunte a la misma dirección.

Por lo que yo sé, una solución portátil para la fundición de un puntero a un tipo x T * es static_cast<T*>(static_cast<void*>(x)), ya static_cast hacia y desde void* está garantizado para convertir un puntero a la misma dirección.

Pero eso solo se relaciona tangencialmente con su pregunta. :)

+0

Esa es una buena solución. static_cast a/from void * está bien, pero ¿también es cierto para múltiples static_cast como static_cast (static_cast (x)) donde x tiene un tipo? Luego reemplazaré todo el elenco de tipo X por el tipo Y como dos static_cast en lugar de uno reinterpret_cast solo para sentirme más seguro. (El compilador que uso GCC & MSVC 9 no hace ningún daño para reinterpret_cast, y no estoy seguro de si otro lo hará. Pero sí, quiero estar del lado más seguro :)) – abir

+3

sí, no lo hago Conozco un compilador en el que la reinterpretación es realmente un problema (y creo que lo harán funcionar como cabría esperar en C++ 0x), pero de acuerdo con el estándar, es un comportamiento indefinido. El truco static_cast debería funcionar para cualquier tipo de puntero. – jalf

+0

'template T pointer_cast (void * p) {return static_cast (p); } ' Eso, más la versión de sobrecarga const ('const void * p'), guardará algunos tipeos. Boost tiene funciones similares, 'static_pointer_cast' y' dynamic_pointer_cast'. –