Typowym (przenośnym) rozwiązaniem jest umieszczenie deklaracji pamięci w zjednoczeniu z dowolnym wbudowanym typem w T
wymagającym najbardziej wyrównania. Najprościej byłoby użyć unii z wszystkich możliwych kandydatów:
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;
mam jeszcze usłyszeć o wiele mniej spotkanie, ekspres do którego powyższa nie wystarczyć. Zwykle wystarcza tylko double
. (Jest to na pewno wystarczające dla firmy Intel i urządzenia Sparc).
W niektórych ekstremalnych przypadkach może to spowodować przydzielenie większej ilości pamięci niż jest to konieczne, np. , np. jeśli T
zawiera tylko jeden lub dwa char
. Większość czasu , to naprawdę nie ma znaczenia, i nie warto martwić, ale jeśli jest dodaje można stosować:
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 ;
} ;
W tym przypadku MaxAlignFor<T>
nigdy nie będzie większy niż T
(i mieć wystarczające wyrównanie, ponieważ wymagane wyrównanie będzie nigdy większe niż nigdy nie będzie większe niż rozmiar T
).
Należy zauważyć, że żadna z powyższych formalnie nie jest gwarantowana przez standard. Ale będzie działać w praktyce.
Masz na myśli 'union' zamiast' enum', prawda? – fredoverflow
Tak. Przykłady jasno to potwierdzają, mam nadzieję. –
@Mehrdad Mówi, że VC++ nie obsługuje pewnej funkcji. Nie mówi, że był to jedyny używany kompilator. –