通常の (移植可能な) 解決策は、メモリ宣言をT
、最もアライメントが必要な組み込み型との共用体に入れることです。最も簡単な方法は、可能性のあるすべての候補でユニオンを使用することです。
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;
上記の方法で十分ではないマシンについて、私はまだ聞いたことがなく、遭遇したこともありません。一般的には、それだけdouble
で十分です。(Intel と Sparc では間違いなく十分です。)
いくつかの極端なケースでは、必要以上のメモリが割り当てられる可能性があります ( T
1 つまたは 2 つの しか含まれていない場合など) char
。ほとんどの場合、これは実際には問題ではなく、心配する価値もありませんが、問題がある場合は、次のように使用できます。
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 ;
} ;
この場合、MaxAlignFor<T>
が よりも大きくなることはありませんT
(また、必要なアラインメントが のサイズよりも大きくなることはないため、十分なアラインメントが必要ですT
)。
これはいずれも、標準によって正式に保証されていないことに注意してください。しかし、それは実際には機能します。