どうやら boost::result_of は __stdcall などの修飾子が付いている関数に対応していないようです。
// これはOK (s_result_type は int) typedef int (* success_t)(); typedef boost::result_of<success_t()>::type s_result_type; s_result_type a = 0; // これはNG (e_result_type は void) typedef int (__stdcall * error_t)(); typedef boost::result_of<error_t()>::type e_result_type; e_result_type b = 0;
Boost.Bindなどを参考に上記のNGのパターンに対応できるようにしてみました。
以下ソース。Gist にも置いてみました。
result_of_s.hpp の先頭の BOOST_RESULT_OF_S_CC を __fastcall に置き換えれば __fastcall な関数にも対応できるつもりですが未確認です。VS2005(VC8)でコンパイルが通ることを確認しています。
// result_of_s.hpp #ifndef BOOST_RESULT_OF_S_HPP #define BOOST_RESULT_OF_S_HPP #ifndef BOOST_RESULT_OF_S_NUM_ARGS # define BOOST_RESULT_OF_S_NUM_ARGS 10 #endif // original #include <boost/utility/result_of.hpp> #define BOOST_RESULT_OF_S_CC __stdcall namespace boost { template<typename F> struct result_of; #if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) namespace detail { template<typename F, typename FArgs, bool HasResultType> struct result_of_impl; template<typename R> struct result_of_void_impl<R (BOOST_RESULT_OF_S_CC *)(void)> { typedef R type; }; template<typename R> struct result_of_void_impl<R (BOOST_RESULT_OF_S_CC &)(void)> { typedef R type; }; } // end namespace detail // result_of_s.hpp と result_of_iterate_s.hpp が同じフォルダにある、という前提 #define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_S_NUM_ARGS,"result_of_iterate_s.hpp")) #include BOOST_PP_ITERATE() #else # define BOOST_NO_RESULT_OF 1 #endif } #undef BOOST_RESULT_OF_S_CC #endif // BOOST_RESULT_OF_S_HPP
// result_of_iterate_s.hpp #if !defined(BOOST_PP_IS_ITERATING) # error Boost result_of - do not include this file! #endif // CWPro8 requires an argument in a function type specialization #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0 # define BOOST_RESULT_OF_S_ARGS void #else # define BOOST_RESULT_OF_S_ARGS BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T) #endif #undef BOOST_RESULT_OF_S_ARGS #if BOOST_PP_ITERATION() >= 1 namespace detail { template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> struct result_of_impl<R (BOOST_RESULT_OF_S_CC *)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> { typedef R type; }; template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> struct result_of_impl<R (BOOST_RESULT_OF_S_CC &)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> { typedef R type; }; #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> struct result_of_impl<R (BOOST_RESULT_OF_S_CC T0::*) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> { typedef R type; }; template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> struct result_of_impl<R (BOOST_RESULT_OF_S_CC T0::*) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) const, FArgs, false> { typedef R type; }; template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> struct result_of_impl<R (BOOST_RESULT_OF_S_CC T0::*) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) volatile, FArgs, false> { typedef R type; }; template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> struct result_of_impl<R (BOOST_RESULT_OF_S_CC T0::*) (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) const volatile, FArgs, false> { typedef R type; }; #endif } #endif