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名の弊害と言える。もちろん、テンプレート実引数は省略できる。なぜならば、オブジェクトの型は、コンパイル時に分かっているからだ。
この手のことは、別に新しいテクニックというわけでもないが、自前でストレージのサイズやアライメントを設定せずにすむので、よりポータブルに書ける。
placement newでこういう事が出来るとはちょっと感激に近い物を感じました。
ReplyDeleteそれ以外の所はかなりC#に似てるなあ・・・結局行き着く所は同じなのかなあ。って前にも書いたような希ガス。