13

C++03 コードでは、特定の型と同じサイズとアラインメントを持つバッファーを移植可能に実装するにはどうすればよいでしょうか?unsigned char[sizeof(T)]T

例えば:

template<class T>
void test()
{
    unsigned char buffer[sizeof(T)];   // <----- how do I ensure this is aligned?
    if (some_condition())
    {
        T *const obj = new(buffer) T();
        // ...
        obj->~T();
    }
    else { /* use 'buffer' for something else */ }
}

これは可能ですか、またはこれを実装するためにコンパイラ拡張機能を使用する必要がありますか?

4

2 に答える 2

7

Guru Of The Week #28コラムで、Herb Sutter はユニオンを使用していますが、Boost の取り組みほど堅牢ではありません。

Boost のaligned_storageは、面倒な詳細を解決してくれます。その実装を見ると、MSCV__alignofまたは GCC__alignof__と別のテンプレートを使用していることがわかります: type_with_alignment.

私自身のコードベースから、私はかつて使用しました(上記のGOTWリンクから派生):

#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706)
#  pragma warning(push)
#  pragma warning(disable: 4371)
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706)
      union AlignedStorage
      {
        char        storage[sizeof(T)];
        int16       dummy0;
        int32       dummy1;
        int64       dummy2;
        float       dummy3;
        double      dummy4;
        long double dummy5;
        void        (*dummy6)();
        struct      dummy7;
        int         dummy7::*dummy8;
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215)
#  pragma warning(push)
#  pragma warning(disable: 4121)
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215)
        int         (dummy7::*dummy9)(int);
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215)
#  pragma warning(pop)
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215)

      }; // AlignedStorage
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706)
#  pragma warning(pop)
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706)

最近では、より多くのコーナーケースとコンパイラの特異性をカバーする可能性が高いため、Boost に頼っています。

于 2013-08-19T21:36:12.457 に答える