Can you extract types from template parameter function signature

前端 未结 1 1891
北恋
北恋 2021-02-06 08:23

Is there a way that I can extract the types from a function signature in the form foo(bar) and get access to just foo or bar. So if I have

相关标签:
1条回答
  • 2021-02-06 08:40

    Here is a very basic solution that works for functions accepting one parameter( it seems you are placing this constraint in the question, but a generalized solution is quite easy to provide, as shown in the following):

    template<typename S>
    struct type; // You can leave this undefined, because the template is
                 // supposed to be instantiated with a function type, and
                 // that is matched by the specialization below.
    
    template<typename R, typename Arg>
    struct type<R(Arg)>
    {
        // Just use R and Args as you wish here..
    };
    

    Here is a possible example (live demo on Coliru):

    #include <type_traits>
    
    template<typename S>
    struct signature;
    
    template<typename R, typename Arg>
    struct signature<R(Arg)>
    {
        using return_type = R;
        using argument_type = Arg;
    };
    
    int main()
    {
        using ret = signature<void(int)>::return_type;
        using arg = signature<void(int)>::argument_type;
    
        static_assert(std::is_same<ret, void>{}, "!");
        static_assert(std::is_same<arg, int>{}, "!");
    }
    

    In case you are interested in a more general solution for the variadic case, this is probably what you're looking for:

    #include <tuple>
    
    struct type; // You can leave this undefined, because the template is
                 // supposed to be instantiated with a function type, and
                 // that is matched by the specialization below.
    
    template<typename R, typename... Args>
    struct type<R(Args...)>
    {
        // Just use R and Args... as you with here..
    };
    

    And here is a possible usage example (live demo on Coliru):

    #include <tuple>
    #include <type_traits>
    
    template<typename S>
    struct signature;
    
    template<typename R, typename... Args>
    struct signature<R(Args...)>
    {
        using return_type = R;
        using argument_type = std::tuple<Args...>;
    };
    
    int main()
    {
        using ret = signature<void(int, double)>::return_type;
        using arg1 = std::tuple_element_t<0, signature<void(int, double)>::argument_type>;
        using arg2 = std::tuple_element_t<1, signature<void(int, double)>::argument_type>;
    
        static_assert(std::is_same<ret, void>{}, "!");
        static_assert(std::is_same<arg1, int>{}, "!");
        static_assert(std::is_same<arg2, double>{}, "!");
    }
    
    0 讨论(0)
提交回复
热议问题