Search code examples
c++functionboostmember

Use Boost to get arity and paramerter types of member function? (boost::function_traits)


It works just fine, for plain vanilla functions. The code below works just fine. It prints just what is should:

int __cdecl(int, char)
2
int,char

#include <boost/type_traits.hpp>
#include <boost/function.hpp>
#include <boost/typeof/std/utility.hpp>

#include <iostream>

using std::cout;
using std::endl;

int foo(int, char) {
 return 0;
}
int main() {
    typedef BOOST_TYPEOF(foo) foo_type;;
    typedef boost::function_traits<foo_type> function_traits;

    cout << typeid(foo_type).name() << endl;
    cout << function_traits::arity << endl;
    cout << typeid(function_traits::arg1_type).name() << ",";
    cout << typeid(function_traits::arg2_type).name() << endl;

    return 0;
}

So, the question is, how can one do this if foo is a member function of class bar?

struct bar {
    int foo(int, char) { return 0; }
};

I have tried countless combinations of these constructs: BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() BOOST_TYPEOF_REGISTER_TYPE() boost::ref boost::remove_pointer boost::bind boost::mem_fn

etc., etc... No joy.


Solution

  • Boost Function Types would probably be the natural solution:

    #include <boost/function_types/function_type.hpp>
    #include <boost/function_types/parameter_types.hpp>
    #include <boost/function_types/function_arity.hpp>
    #include <boost/typeof/std/utility.hpp>
    #include <boost/typeof/typeof.hpp>
    #include <iostream>
    
    struct bar {
        int foo(int, char) { return 0; }
    };
    
    int main() {
    
        typedef BOOST_TYPEOF(&bar::foo) foo_type;
    
        std::cout << typeid(foo_type).name() << std::endl;
        std::cout << boost::function_types::function_arity<foo_type>::value << std::endl;
        std::cout << typeid(boost::mpl::at_c<boost::function_types::parameter_types<foo_type>,1>::type).name() << ",";
        std::cout << typeid(boost::mpl::at_c<boost::function_types::parameter_types<foo_type>,2>::type).name() << ",";
    
        return 0;
    }