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)の方がいい。