2011-08-05 8 views
6

私はタイプTのオブジェクトの基本的なメモリとして使用されている配列を持っている:どのようにしてアライナ(T)をシミュレートできますか?

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

にはどうすればmemoryTオブジェクトに対して正しく整列されていることを確認することができますか? C++ 0xでは、私はちょうど言うことができる:

alignas(T) char memory[sizeof T]; 

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

答えて

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で十分です。 (インテルと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より大きくならないためです)。

これは公式に規格で保証されていないことに注意してください。しかし、実際には が動作します。

+0

あなたは 'enum'の代わりに' union'を意味します、そうですか? – fredoverflow

+0

はい。その例は、明らかにしました、私は願っています。 –

+0

@Mehrdad VC++は特定の機能をサポートしていないと言います。これが唯一のコンパイラであるとは言いません。 –

5

vc++ alignのグーグル表示this page__declspec(align(#))を使用してください。

+4

は、コンパイラ固有の拡張機能です。 –

+1

@JamesKanze:これは3年遅れているが、私はとにかくそれを言及よ...それは問題のビジュアルC++を言うん:) – Mehrdad

+0

@JamesKanze:申し訳ありませんが、私は実際に自分の携帯電話でコメントし、私は「実現しませんでした間違った投稿にコメントしています。あなたの投稿の私の返信はここにあなたのコメントに答えて、ここにあることを意味しました。 – Mehrdad

2

ヒープ上のメモリ(アラインメント保証がある)を割り当てるか、boost::aligned_storageを使用してください。

3

Tが標準レイアウトであり、組合がよく、その後、形成されている

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

が整列されなければならない場合。先頭の `__`明らかに、示すように、

関連する問題