C++11 で Boost.MPL.lambda みたいなの書いてみた
書いたことがなかったので書いてみた。
[コード]
#include <utility> #include <tuple> template<std::size_t Index> struct placeholder{ template<typename... Args> struct apply : std::tuple_element<Index, std::tuple<Args...>>{}; template<typename... Args> using apply_t = typename apply<Args...>::type; }; using _1 = placeholder<0>; using _2 = placeholder<1>; static_assert(std::is_same<_1::apply<int, double>::type, int>{}, ""); static_assert(std::is_same<_2::apply<int, double>::type, double>{}, ""); template<typename Expr, typename... Args> struct invoke{ template<typename Expr_, typename... Args_> static typename Expr_::template apply<Args_...>::type helper(bool); template<typename Expr_, typename... Args_> static Expr_ helper(int); using type = decltype(helper<Expr, Args...>(true)); }; template<typename Expr, typename... Args> using invoke_t = typename invoke<Expr, Args...>::type; template<typename... Args> struct lambda; template< template<class...> class Expr, typename... Placeholders > struct lambda<Expr<Placeholders...>>{ template<typename... Args> struct apply : std::common_type<Expr<typename ::invoke<Placeholders, Args...>::type...>>{}; template<typename... Args> using apply_t = typename apply<Args...>::type; }; using is_int = lambda<std::is_same<int, _1>>; static_assert(is_int::apply_t<int>{}, ""); static_assert(!is_int::apply_t<float>{}, ""); static_assert(std::is_same< lambda<std::tuple<_2, _1>>::apply_t<int, float>, std::tuple<float, int> >{}, ""); int main(){ return 0; }
使ってるのは Variadic Templates と Template Aliases ぐらいですかねえ。
逆に使い勝手自体は C++03 とあんまり変わらないのでうーむ・・・