今日は野良仕事をしに行っていたわけだが、まぁこのことは後に書くとしよう。
正味の仕事は3時間ほどだったので大したことはなかったが、これでもかなりの効果はあったようで。
手伝いに行った意味もあったものだ。
C++0xやるかと思って、改めてVisual Studio 2010のBeta版を入れてみた。今のところ一番いけてるコンパイラだと思う。(参考記事 : C++0xの化け物じみた右辺値参照)
これを見ると結構いろいろな機能に対応しているね。なかなかよい。
その上でいろいろ試していたのだが、おもしろいこともあるもんだ。
std::unique_ptrという右辺値参照を活用したスマートポインタがあるのだが、これってコンテナに入れられたかなと思って実験してみた。
std::vector<std::unique_ptr<std::string>> v(1);
std::unique_ptr<std::string> p1(new std::string("hage"));
v.at(0)=std::move(p1);
v.push_back(std::unique_ptr<std::string>(new std::string("hoge")));
なんか平然と入れられるし。
std::move付け忘れるとどうなるかって話ですが、へんなエラーが出てコンパイルに失敗する。
まぁしかしこれがいけるならshared_ptrよりもシンプルでいいよね。unique_ptr万歳!
これを回すときですが、せっかくなのでfor_eachしてみた。
std::for_each(v.begin(),v.end(),[](std::unique_ptr<std::string>& p){
std::cout << *p << std::endl;
});
shared_ptrと違ってコピーできないので参照渡ししないとならん。constは必要に応じてどうぞ。
果たしてこう言うのが便利なのかと言われると難しいが、他のところにコピーして渡す気さえなければいいんじゃないの。
さて、もう左辺値を破壊してしまってもかまわないときにはstd::moveを使うのですが、std::forwardというのもある。
これはテンプレートに関係がある。
template <typename T>
Test TestCreator(T&& other){
return Test(other);
}
こんなテンプレート関数があったとき、Tの型名は自動で推論される。
もしTest型の右辺値を渡せばT=Testとなるのは容易に予想できる。
ところがTest型の左辺値を渡すとT=Test&となってこのテンプレートが使われる。
なんでやねんという話だがT& &やT& &&やT&& &はT&になるというルールがあるらしく、Test& &&はTest&と同じ意味になってしまうから。
まぁなんにせよ、こう書いておけば右辺値も左辺値も歓迎と言うことになる。
ここで元が右辺値ならstd::moveしたいが、元が右辺値であるかチェックしたいと。
そこでstd::forwardで、これを使うことで判別して適当にしてくれると。
return Test(std::forward<T>(other));
こんな風に書けば、自動で判定して適当な処理をしてくれる。
右辺値か左辺値かまで完全に転送するからPerfect Forwardingなんだと。
これを見て初めて理解できた。
それにしてもこの機能はすばらしいね。C++0xすばらしい。
しかしそんな風に言ってますが、C++0xは2000年代にリリースできなかったんですよね。
本来ならC++09みたいになるはずだったのに失敗してしまったと。
果たしてどういう方向にまとまるのか。できるだけ早くまとめてほしいところ。
以下に素晴らしくてもコンパイラが対応してないと使えないもん。