5

タイプのオブジェクトの基になるメモリとして使用される配列がありますT:

char memory[sizeof T];
.
.
.
new(memory) T(whatever);

オブジェクトに対してmemoryが正しく配置されていることを確認するにはどうすればよいですか? TC++0x では、次のように言えます。

alignas(T) char memory[sizeof T];

しかし、Visual Studio 2010 はその特定の機能をまだサポートしていません。

4

4 に答える 4

10

通常の (移植可能な) 解決策は、メモリ宣言を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 では間違いなく十分です。)

いくつかの極端なケースでは、必要以上のメモリが割り当てられる可能性があります ( T1 つまたは 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)。

これはいずれも、標準によって正式に保証されていないことに注意してください。しかし、それは実際には機能します。

于 2011-08-05T16:31:34.523 に答える
5

グーグルで検索すると、このページvc++ alignが表示されます: use .__declspec(align(#))

于 2011-08-05T16:08:06.330 に答える
3

T が標準レイアウトであり、和集合が適切に形成されている場合、

union
{
   T t;
   char memory[sizeof T];
};

整列する必要があります。

于 2011-08-05T16:43:15.597 に答える
2

(アラインメントが保証されている) ヒープにメモリを割り当てるか、boost::aligned_storage.

于 2011-08-05T16:19:50.730 に答える