メタプログラミング難しいし、モナド則にちゃんと則ってるかよくわかんないし。
メタプログラミング難しいし、モナド則にちゃんと則ってるかよくわかんないし。
#include <cstdio> #include <boost/optional.hpp> #include <boost/type_traits.hpp> #include <boost/utility/result_of.hpp> template <typename T> struct is_optional : public boost::false_type { }; template <typename T> struct is_optional<boost::optional<T> > : public boost::true_type { }; template <typename T, typename F, typename Reserver = typename boost::disable_if<is_optional<typename boost::result_of<F(T)>::type>>::type, typename Reserver2 = typename boost::disable_if<boost::is_void<typename boost::result_of<F(T)>::type>>::type > inline boost::optional<typename boost::result_of<F(T)>::type> operator >> (boost::optional<T> val, F func) { if (val) { return func(*val); } else { return boost::none; } } template <typename T, typename F, typename Reserver = typename boost::enable_if<is_optional<typename boost::result_of<F(T)>::type>>::type> inline typename boost::result_of<F(T)>::type operator >> (boost::optional<T> val, F func) { if (val) { return func(*val); } else { return boost::none; } } template <typename T, typename F, typename Reserver = typename boost::enable_if<boost::is_void<typename boost::result_of<F(T)>::type>>::type> inline void operator >> (boost::optional<T> val, F func) { if (val) { return func(*val); } } boost::optional<int> testFunc(int n) { return (n % 2 == 0)? n/2 : boost::optional<int>(); } int testFunc2(int n) { return n / 2; } int main(int argc, const char * argv[]) { testFunc(32) >> [] (int r) { return testFunc(r); } >> [] (int r) { return testFunc2(r); } >> [] (int r) { std::printf("%d", r); } ; }