La solución habitual (portátil) es poner la declaración de memoria en una unión con cualquier tipo incorporado en T
requiere la mayor alineación. La forma más sencilla sería utilizar una unión con todos los posibles candidatos :
union MaxAlign
{
int i ;
long l ;
long long ll ;
long double ld ;
double d ;
void* p ;
void (* pf)() ;
MaxAlign* ps ;
} ;
union
{
MaxAlign dummyForAlignment;
unsigned char memory[sizeof(T)];
} rawT;
todavía tengo que oír hablar, y mucho menos encuentro, una máquina en la que por encima de no fue suficiente. Generalmente, solo double
es suficiente. (Definitivamente es suficiente en Intel y en Sparc.)
En algunos casos extremos, esto puede dar como resultado la asignación de más memoria que necesaria, p. si T
solo contiene uno o dos char
. La mayoría de las veces , esto realmente no importa, y no vale la pena preocuparse, pero si que es, lo siguiente puede ser utilizado:
namespace MyPrivate {
template< typename T, bool isSmaller >
struct AlignTypeDetail ;
template< typename T >
struct AlignTypeDetail< T, false >
{
typedef T type ;
} ;
template< typename T >
struct AlignTypeDetail< T, true >
{
typedef char type ;
} ;
template< typename T, typename U >
struct AlignType
{
typedef typename AlignTypeDetail< U, (sizeof(T) < sizeof(U)) >::type
type ;
} ;
}
template< typename T >
union MaxAlignFor
{
typename MyPrivate::AlignType< T, char >::type c ;
typename MyPrivate::AlignType< T, short >::type s ;
typename MyPrivate::AlignType< T, int >::type i ;
typename MyPrivate::AlignType< T, long >::type l ;
typename MyPrivate::AlignType< T, long long >::type ll ;
typename MyPrivate::AlignType< T, float >::type f ;
typename MyPrivate::AlignType< T, double >::type d ;
typename MyPrivate::AlignType< T, long double >::type ld ;
typename MyPrivate::AlignType< T, void* >::type pc ;
typename MyPrivate::AlignType< T, MaxAlign* >::type ps ;
typename MyPrivate::AlignType< T, void (*)() >::type pf ;
} ;
En este caso, MaxAlignFor<T>
nunca habrá más grande que T
(y tener una alineación suficiente, ya que la alineación requerida será nunca será mayor que el tamaño de T
).
Tenga en cuenta que nada de esto está formalmente garantizado por la norma. Pero funcionará en la práctica.
¿Quiere decir 'union' en lugar de' enum', ¿verdad? – fredoverflow
Sí. Los ejemplos lo aclararon, espero. –
@Mehrdad Dice que VC++ no admite una determinada función. No dice que este fue el único compilador utilizado. –