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:
placement newでこういう事が出来るとはちょっと感激に近い物を感じました。
それ以外の所はかなりC#に似てるなあ・・・結局行き着く所は同じなのかなあ。って前にも書いたような希ガス。
Post a Comment