I am working on this problem, and I have managed to get the boost interpreter to accept a member function, for example:
// Registers a function with the interpreter, // will not compile if it a member function. template<typename Function> typename boost::enable_if< ft::is_nonmember_callable_builtin<Function> >::type register_function(std::string const& name, Function f); // Registers a member function with the interpreter. // Will not compile if it a non-member function. template<typename Function, typename TheClass> typename boost::enable_if< ft::is_member_function_pointer<Function> >::type register_function(std::string const& name, Function f, TheClass* theclass);
The enable_if statement is used to prevent the use of the wrong method at compile time. Now what you need to understand:
- It uses boost :: mpl to analyze, by parameters, the argument of the called inline argument (which is basically a function pointer).
- Then it prepares a merge vector at compile time (which is a vector that can simultaneously store different objects of different types).
- When mpl parses all arguments, the parsing method will use the fork in the invoke apply method, following the patterns.
- The main problem is that the first argument of the member called by the inline is an object that contains the called method.
- As far as I know, mpl cannot parse the arguments of something other than the called inline (i.e. the result of A Boost :: Bind)
So, what needs to be done, just add one step to the โparsingโ, which would be to add the corresponding object to the application loop! Here it is:
template<typename Function, typename ClassT> typename boost::enable_if< ft::is_member_function_pointer<Function> >::type interpreter::register_function( std::string const& name, Function f, ClassT* theclass); { typedef invoker<Function> invoker;
in the interpreter :: invoker
template<typename Args, typename TheClass> static inline void apply_object( Function func, TheClass* theclass, parameters_parser & parser, Args const & args) { typedef typename mpl::next<From>::type next_iter_type; typedef interpreter::invoker<Function, next_iter_type, To> invoker; invoker::apply( func, parser, fusion::push_back(args, theclass) ); }
Thus, he will simply skip the first type of argument and analyze everything correctly. The method can be called as follows: invoker.register_function("SomeMethod",&TheClass::TheMethod,&my_object);