Boost.Phoenix と decltype を組み合わせる

以前も似たような事をやったんですが、Boost.Phoenix と decltype の組み合わせで面白いことができますね。

[ソース]

#include <memory>
#include <iostream>
#include <boost/mpl/int.hpp>
#include <boost/mpl/string.hpp>
#include <boost/phoenix.hpp>
#include <boost/multi_index/mem_fun.hpp>


struct disp_impl{
    typedef void result_type;

    template<typename T>
    void operator ()(T) const{
        std::cout << T::value << std::endl;
    }
};

boost::phoenix::function<disp_impl> const disp;

struct hoge{
    ~hoge(){
        std::cout << "hoge delete" << std::endl;
    }
};

int
main(){
    namespace mpl = boost::mpl;
    namespace phx = boost::phoenix;
    using phx::arg_names::arg1;
    std::unique_ptr<
        hoge,
        decltype(
            phx::delete_(arg1),
            disp(mpl::c_str<mpl::string<'dele', 'ted'>>())
        )
    >    p(new hoge);

    return 0;
}

return 0;
}

[出力]

hoge delete
deleted

テンプレート引数に lambda expression を渡すことは出来ないんですが、Boost.Phoenix の戻り値型(Expression Template) からそれっぽい事を行うことができますね。
decltyep 素晴らしい。
型しか保持することは出来ないのでちと悲しいんですが、面白いですよねー。
一応、整数、小数リテラルであれば User-defined literals で型を作れるんですがね。

[boost]

  • ver 1.48.0

[コンパイラ]

  • g++ (GCC) 4.7.0 20111112 (experimental)