4

This is a follow up on How do I get the argument types of a function pointer in a variadic template class?

I have this struct to access the arguments of a variadic template:

template<typename T> 
struct function_traits;  

template<typename R, typename ...Args> 
struct function_traits<std::function<R(Args...)>>
{
    static const size_t nargs = sizeof...(Args);

    typedef R result_type;

    template <size_t i>
    struct arg
    {
        typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
    };
};

And I access the type of an argument of Args with

typedef function<void(Args...)> fun;
std::cout << std::is_same<int, typename function_traits<fun>::template arg<0>::type>::value << std::endl;

However, I would like to iterate through the arguments to be able to handle an arbitrary number of arguments. The following doesn't work, but to illustrate what I want:

for (int i = 0; i < typename function_traits<fun>::nargs ; i++){ 
    std::cout << std::is_same<int, typename function_traits<fun>::template arg<i>::type>::value << std::endl;
}
Community
  • 1
  • 1
steffen
  • 8,572
  • 11
  • 52
  • 90

1 Answers1

6

You'd need to do a compile-time iteration along the lines of

template <typename fun, size_t i> struct print_helper {
    static void print() {
        print_helper<fun, i-1>::print();
        std::cout << std::is_same<int, typename function_traits<fun>::template arg<i-1>::type>::value << std::endl;
    }
};

template <typename fun> struct print_helper<fun,0> {
    static void print() {}
};

template <typename fun> void print() {
    print_helper<fun, function_traits<fun>::nargs>::print();
}
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Thank you, @Mike. I figured, it must be recursive and at compile time, I just didn't manage to put it together ;) BUT: `fun` is unknown in the scope. I tried to pass `fun` along as a template parameter, but in the specialisation, the compiler complains, `function template partial specialization ‘print<0, fun>’ is not allowed`. My specialisation reads: `template void print<0,fun>() {}` – steffen Jan 31 '12 at 10:36
  • @steffen: No, you can't partially specialise function templates, only class templates. I guess you'll need to wrap the functions in classes; I'll update the answer. – Mike Seymour Jan 31 '12 at 10:41