optionalとbindとphoenix
boost::optional::getをbindにかけたいと思っていろいろ試したメモ
結論はphoenix使え。
以下いろいろ試したソース
#include<iostream> #include<boost/optional.hpp> #include<boost/phoenix/phoenix.hpp> #include<boost/lambda/lambda.hpp> int main(const int argc,const char** argv) { using boost::phoenix::bind; using boost::phoenix::arg_names::arg1; boost::optional<int> opt(4); // (1) std::cout << opt.get() << std::endl; // OK std::cout << *opt << std::endl; // OK // (2-1) (std::cout << *arg1 << std::endl)(opt); // OK std::cout << (*arg1)(opt) << std::endl; // OK // (2-2) // (std::cout << *boost::lambda::_1 << "\n")(opt); // lambdaだとNG // std::cout << (*boost::lambda::_1)(opt) << std::endl; // もちろんこれもNG // (3-1) // std::cout << // bind(&boost::optional<int>::get, arg1)(opt) // NG // << std::endl; // (3-2) std::cout << bind( static_cast<int const&(boost::optional<int>::*)()const> (&boost::optional<int>::get), arg1)(opt) // OK << std::endl; // (3-3) (std::cout << bind( static_cast<int const&(boost::optional<int>::*)()const> (&boost::optional<int>::get), arg1) << std::endl)(opt); // OK return 0; }
(1)は普通にoptionalを使う場合。やりたいのはこれの関数化
(2-1)はphoenixを使って関数化して、引数にoptを渡している。っていうかこれで十分bindいらない。
(2-2)は(2-1)と似てるけど、Boost.Lambdaバージョン。これはコンパイル通らない。さっさとBoost.Phoenixに乗り換えよう。
(3-1,2,3)は問題のbindで呼び出すパターン。(3-1)は通らない。(3-2,3)はコンパイル通る。けど普通の人はこんなのすぐに書けない、よね?
(3-3)を使えば(std::cout..)を関数化できるけど、どう考えても(2-1)の方がいい。