lvalue/rvalueに応じて挙動を変える
range adaptorを作ろうとしてるときに考えていたのが発端.
与えたrangeから何かしら別のrangeを作って返すようなことがしたい時,既に存在するrangeを渡すこともあればboost::irangeなんかで作ったrvalue refなrangeを渡したくなることもあります.
パラメータがlvalueならそのまま参照を持ち,rvalueであればmoveしてキャプチャしてしまうような挙動が望ましいと思ったのですが今ひとつ実装が浮かばず放っておいたのですがそれっぽいのができました.
全体はこれ=>Ideone.com - ELarMP - Online C++0x Compiler & Debugging Tool.
こんな感じにしてやるとlvalueを渡せばlvalue ref, rvalueを渡せばmoveしてlvalueで持ちます.
moveのし忘れが無ければオブジェクトの寿命が切れてしまってどうしようもないというのはなんとかできそうですかね.
template<typename...Args> struct Foo { Foo(Args&&... args) : t_(std::forward<Args>(args)...) { } ... std::tuple<Args...> t_; }; // lvalue refならlvelue refのまま扱う template<typename...Args> auto foo(Args&... args) -> Foo<Args&...> { return Foo<Args&...>{args...}; } // rvalue refならmoveする template<typename...Args> auto foo(Args&&... args) -> Foo<Args...> { return Foo<Args...>{std::forward<Args>(args)...}; }
std::forwardさん素敵.
ついでにVariadic Templateでメタメタしたコードを個別に書くのに疲れたのでboost::fusionの練習.