Get argument type of template callable object

后端 未结 4 1567
不知归路
不知归路 2020-12-09 04:33

Consider the following function:

template
void register_handler( F& f ) // any callable object
{
   // find out T - the argument type of f         


        
4条回答
  •  盖世英雄少女心
    2020-12-09 04:52

    This blogpost shows how to implement some function type traits. These should work with everything callable (exception: polymorphic functors :P). You could iterate over the arguments, and use their type to do some sfinae or as a additional template argument.

    Function traits as copied from blogpost:

    #include 
    
    // as seen on http://functionalcpp.wordpress.com/2013/08/05/function-traits/
    template
    struct function_traits;
    
    // function pointer
    template
    struct function_traits : public function_traits
    {};
    
    template
    struct function_traits
    {
        using return_type = R;
    
        static constexpr std::size_t arity = sizeof...(Args);
    
        template 
        struct argument
        {
            static_assert(N < arity, "error: invalid parameter index.");
            using type = typename std::tuple_element>::type;
        };
    };
    
    // member function pointer
    template
    struct function_traits : public function_traits
    {};
    
    // const member function pointer
    template
    struct function_traits : public function_traits
    {};
    
    // member object pointer
    template
    struct function_traits : public function_traits
    {};
    
    // functor
    template
    struct function_traits
    {
        private:
            using call_type = function_traits;
        public:
            using return_type = typename call_type::return_type;
    
            static constexpr std::size_t arity = call_type::arity - 1;
    
            template 
            struct argument
            {
                static_assert(N < arity, "error: invalid parameter index.");
                using type = typename call_type::template argument::type;
            };
    };
    
    template
    struct function_traits : public function_traits
    {};
    
    template
    struct function_traits : public function_traits
    {};
    

    Testcode:

    #include 
    
    class A
    {
    };
    
    template 
    struct Functor
    {
      void operator()(const T& t)
      {}
    };
    
    struct Register
    {
      //int parameters
      template 
      static void RegisterFunctor(const T& /*functor*/, typename std::enable_if::template argument<0>::type, const int&>::value>::type* = 0)
      {
        std::cout << "Register int func" << std::endl;
      }
    
      //A parameters
      template 
      static void RegisterFunctor(const T& /*functor*/, typename std::enable_if::template argument<0>::type, const A&>::value>::type* = 0)
      {
        std::cout << "Register int func" << std::endl;
      }
    };
    
    void intFunc(const int&) {}
    void aFunc(const A&){}
    
    int main(int /*argc*/, char */*argv*/[])
    {
      Functor intFunctor;
      Functor aFunctor;
    
      Register::RegisterFunctor(intFunctor);
      Register::RegisterFunctor(&intFunc);
      Register::RegisterFunctor(aFunctor);
      Register::RegisterFunctor(&aFunc);
      return 0;
    }
    

提交回复
热议问题