dimanche 31 juillet 2016

How to get all parameters' types from parameter pack?

I have the following piece of code where I define struct quick with templated static method random with some specializations:

( I used function_traits from other SO answer. Attached on the bottom for reference.)

struct quick
{
  template <typename T>
  static T random();

  template <typename F>
  static void check(F f)
  {

    constexpr auto arity = function_traits<F>::arity; // easy :)
    std::cout << arity << std::endl;
    typedef typename function_traits<F>::template arg<0>::type type0; // easy:)
    // how to get all types of all F's parameters?
  }
};

template <>
std::string quick::random<std::string>()
{
  return std::string("test");
}

template <>
int quick::random<int>()
{
  return 1;
}

I would like to get all types of F's parameters inside check so that I can generate a tuple with random entries (based on my random method specializations).

I tried with something like:

template<typename F, typename ...TIdxs>
using ArgTypes = typename function_traits<F>::template arg<TIdxs>::type...;

// ...
// inside check

typedef ArgTypes<F, std::make_index_sequence<arity>> types;

but failed miserably:

main.cpp:80:72: error: expected ‘;’ before ‘...’ token
 using ArgTypes = typename function_traits<F>::template arg<TIdxs>::type...;
                                                                        ^
main.cpp: In static member function ‘static void quick::check(F, D)’:
main.cpp:98:15: error: ‘ArgTypes’ does not name a type
       typedef ArgTypes<F, std::make_index_sequence<arity>> types;


I have used function traits utilities from this SO answer.

template <typename T>
struct function_traits : function_traits<decltype(&T::operator())>
{};
// For generic types, directly use the result of the signature of its 'operator()'

template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
    enum { arity = sizeof...(Args) };
    // arity is the number of arguments.

    typedef ReturnType result_type;

    template <size_t i>
    struct arg
    {
        typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
        // the i-th argument is equivalent to the i-th tuple element of a tuple
        // composed of those arguments.
    };
};

Aucun commentaire:

Enregistrer un commentaire