2010-10-29

C++0xのUnion

C++0xでは、unionの制限がかなり取り払われたので、こんなことができる。

union U
{
    std::string str ;
    std::vector<int> vec ;

    // コンストラクターとデストラクターは、暗黙的にdeleteされているので、
    // ユーザー定義が必要。
    U() { }
    ~U() { }
} ;

int main()
{
    U u ;

    new ( &u.str ) std::string( "hello" ) ;
    std::cout << u.str << std::endl ;
    u.str.~basic_string() ;

    new ( &u.vec ) std::vector<int> { 1, 2, 3 } ;
    for ( auto i : u.vec )
    { std::cout << i << std::endl ; }
    u.vec.~vector() ;

}

まあ、なんのことはない。Uのオブジェクトは、std::stringとstd::vector<int>のどちらかを格納できるだけのサイズを持っているし、またアライメント要求なども適切に行われるので、placement newができるという話だ。

最初、~basic_stringと書くべきところを、~stringと書いてしまい、エラーになった。typedef名の弊害と言える。もちろん、テンプレート実引数は省略できる。なぜならば、オブジェクトの型は、コンパイル時に分かっているからだ。

この手のことは、別に新しいテクニックというわけでもないが、自前でストレージのサイズやアライメントを設定せずにすむので、よりポータブルに書ける。

1 comment:

萌ゑ said...

placement newでこういう事が出来るとはちょっと感激に近い物を感じました。

それ以外の所はかなりC#に似てるなあ・・・結局行き着く所は同じなのかなあ。って前にも書いたような希ガス。