Boost.Phoenix で、ユーザ側で定義した関数を呼び出すためのアダプタ
boost::phoenix::function を使用して定義することも出来ますが、Boost.Phoenix に用意されているアダプタを使用すればもっと簡単に定義することが出来ます。
BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY
引数のない関数をアダプトします。
namespace demo{ int nullary_func(){ return 42; } } // namespace demo // 引数なしの関数を定義 BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY( int, // 戻り値型 nullary_func, // 定義する関数名 demo::nullary_func // 呼び出す関数名 ) assert((arg1 + nullary_func())(1) == 44);
BOOST_PHOENIX_ADAPT_FUNCTION
引数がある関数をアダプトします。
namespace demo{ int plus(int a, int b){ return a + b; } template<typename T> T plus(T a, T b, T c){ return a + b + c; } } // namespace demo // 引数ありの関数を定義 BOOST_PHOENIX_ADAPT_FUNCTION( int, // 戻り値型 plus, // 定義する関数名 demo::plus, // 呼び出す関数名 2 // 引数の数 ) // 引数型によって、戻り値型が変わる場合 BOOST_PHOENIX_ADAPT_FUNCTION( // A0 .. An が、引数型として使用出来る typename boost::remove_reference<A0>::type, plus, demo::plus, 3 ) assert(plus(arg1, arg2)(5, 2) == 7); assert(plus(arg1, arg2, 3)(5, 2) == 10);
BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY
引数がない関数オブジェクトをアダプトします。
namespace demo{ struct nullary_callable{ typedef int result_type; result_type operator ()() const{ return 42; } }; } // namespace demo // 引数なしの関数オブジェクトを定義 BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY( nullary_callable, // 定義する関数名 demo::nullary_callable // 呼び出す関数名 ) assert((arg1 + nullary_callable())() == 42);
BOOST_PHOENIX_ADAPT_CALLABLE
引数がある関数オブジェクトをアダプトします。
namespace demo{ struct minus{ template<typename Sig> struct result; template<typename This, typename A0, typename A1> struct result<This(A0, A1)> : boost::remove_reference<A0>{}; template<typename This, typename A0, typename A1, typename A2> struct result<This(A0, A1, A2)> : boost::remove_reference<A0>{}; template<typename A0, typename A1> typename result<minus(A0, A1)>::type operator ()(A0 const& a0, A1 const& a1) const{ return a0 - a1; } template<typename A0, typename A1, typename A2> typename result<minus(A0, A1, A2)>::type operator ()(A0 const& a0, A1 const& a1, A2 const& a2) const{ return a0 - a1 - a2; } }; } // namespace demo // 引数ありの関数オブジェクトを定義 BOOST_PHOENIX_ADAPT_CALLABLE( minus, // 定義する関数名 demo::minus, // 呼び出す関数名 2 // 引数の数 ) BOOST_PHOENIX_ADAPT_CALLABLE( minus, demo::minus, 3 ) assert(minus(arg1, arg2)(5, 2) == 3); assert(minus(arg1, arg2, 3)(5, 2) == 0);
[ソース]
#include <boost/phoenix/function/adapt_function.hpp> #include <boost/phoenix/function/adapt_callable.hpp> #include <boost/phoenix/core/argument.hpp> #include <boost/phoenix/operator.hpp> namespace demo{ int nullary_func(){ return 42; } int plus(int a, int b){ return a + b; } template<typename T> T plus(T a, T b, T c){ return a + b + c; } struct nullary_callable{ typedef int result_type; result_type operator ()() const{ return 42; } }; struct minus{ template<typename Sig> struct result; template<typename This, typename A0, typename A1> struct result<This(A0, A1)> : boost::remove_reference<A0>{}; template<typename This, typename A0, typename A1, typename A2> struct result<This(A0, A1, A2)> : boost::remove_reference<A0>{}; template<typename A0, typename A1> typename result<minus(A0, A1)>::type operator ()(A0 const& a0, A1 const& a1) const{ return a0 - a1; } template<typename A0, typename A1, typename A2> typename result<minus(A0, A1, A2)>::type operator ()(A0 const& a0, A1 const& a1, A2 const& a2) const{ return a0 - a1 - a2; } }; } // namespac demo // 引数なしの関数を定義 BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY( int, // 戻り値型 nullary_func, // 定義する関数名 demo::nullary_func // 呼び出す関数名 ) // 引数ありの関数を定義 BOOST_PHOENIX_ADAPT_FUNCTION( int, // 戻り値型 plus, // 定義する関数名 demo::plus, // 呼び出す関数名 2 // 引数の数 ) // 引数型によって、戻り値型が変わる場合 BOOST_PHOENIX_ADAPT_FUNCTION( // A0 .. An が、引数型として使用出来る typename boost::remove_reference<A0>::type, plus, demo::plus, 3 ) // 引数なしの関数オブジェクトを定義 BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY( nullary_callable, // 定義する関数名 demo::nullary_callable // 呼び出す関数名 ) // 引数ありの関数オブジェクトを定義 BOOST_PHOENIX_ADAPT_CALLABLE( minus, // 定義する関数名 demo::minus, // 呼び出す関数名 2 // 引数の数 ) BOOST_PHOENIX_ADAPT_CALLABLE( minus, demo::minus, 3 ) #include <iostream> int main(){ namespace phx = boost::phoenix; using phx::arg_names::arg1; using phx::arg_names::arg2; using phx::arg_names::arg3; (std::cout << arg1 << ":" << nullary_func() << std::endl)(10); (std::cout << plus(arg1, arg2) << std::endl )(3, 2); (std::cout << plus(arg1, arg2, arg3) << std::endl )(0.52f, 2.24f, -1.44f); (std::cout << arg1 + nullary_callable() << std::endl)(20); (std::cout << minus(arg1, arg2) << std::endl )(3, 2); (std::cout << minus(arg1, arg2, 1) << std::endl )(3, 2); return 0; }
[出力]
10:42 5 1.32 62 1 0
[boost]
- ver 1.47.0