Get the type of the return value in C++

前端 未结 2 474
我寻月下人不归
我寻月下人不归 2021-01-04 20:56

Suppose we have a function f which returns a value of some unknown type (let\'s call it T) and takes a value of the type T as an argum

相关标签:
2条回答
  • 2021-01-04 21:11

    Building on @Piotr S.'s excellent answer, for arbitrary functor types, if you know that there's exactly one operator() overload with the right "pattern", so to speak, then you can do something like this:

    // leave undefined
    template<class C, class T>
    T return_type_helper(T (C::*)(T));
    
    template<class C, class T>
    T return_type_helper(T (C::*)(T) const);
    
    // 10 additional combinations of ref- and cv- qualifiers omitted, because I'm lazy
    
    template<typename T>
    using functor_return_type = decltype(return_type_helper(&T::operator()));
    

    This activates overload resolution and template argument deduction to determine the right operator().

    And then you can combine those two:

    template <typename... T>
    struct voider { using type = void; };
    
    template <typename... T>
    using void_t = typename voider<T...>::type;
    
    template<typename T, typename = void>
    struct combined_return_type;
    
    template<typename T>
    struct combined_return_type<T, void_t<typename return_type<T>::type>> { 
        using type = typename return_type<T>::type;
    };
    
    template<typename T>
    struct combined_return_type<T, void_t<functor_return_type<T>>> { 
        using type = functor_return_type<T>; 
    };
    
    template <typename T>
    using return_type_t = typename combined_return_type<T>::type;
    

    Demo.

    0 讨论(0)
  • 2021-01-04 21:17
    template <typename T>
    struct return_type;
    
    template <typename R, typename... Args>
    struct return_type<R(Args...)> { using type = R; };
    
    template <typename R, typename... Args>
    struct return_type<R(*)(Args...)> { using type = R; };
    
    template <typename R, typename C, typename... Args>
    struct return_type<R(C::*)(Args...)> { using type = R; };
    
    template <typename R, typename C, typename... Args>
    struct return_type<R(C::*)(Args...) &> { using type = R; };
    
    template <typename R, typename C, typename... Args>
    struct return_type<R(C::*)(Args...) &&> { using type = R; };
    
    template <typename R, typename C, typename... Args>
    struct return_type<R(C::*)(Args...) const> { using type = R; };
    
    template <typename R, typename C, typename... Args>
    struct return_type<R(C::*)(Args...) const&> { using type = R; };
    
    template <typename R, typename C, typename... Args>
    struct return_type<R(C::*)(Args...) const&&> { using type = R; };
    
    template <typename R, typename C, typename... Args>
    struct return_type<R(C::*)(Args...) volatile> { using type = R; };
    
    template <typename R, typename C, typename... Args>
    struct return_type<R(C::*)(Args...) volatile&> { using type = R; };
    
    template <typename R, typename C, typename... Args>
    struct return_type<R(C::*)(Args...) volatile&&> { using type = R; };
    
    template <typename R, typename C, typename... Args>
    struct return_type<R(C::*)(Args...) const volatile> { using type = R; };
    
    template <typename R, typename C, typename... Args>
    struct return_type<R(C::*)(Args...) const volatile&> { using type = R; };
    
    template <typename R, typename C, typename... Args>
    struct return_type<R(C::*)(Args...) const volatile&&> { using type = R; };
    
    template <typename T>
    using return_type_t = typename return_type<T>::type;
    

    Test:

    #include <type_traits>
    
    struct Functor
    {
        int operator()(int i, int j) { return i + j; }
    };
    
    template <class F>
    struct A
    {
        using T = return_type_t<decltype(&F::operator())>;
    
        T some_function(T some_arg) { return some_arg; }
    };
    
    int main()
    {
        A<Functor> a;
        static_assert(std::is_same<decltype(a.some_function(1)), int>::value, "!");
    }
    

    DEMO

    0 讨论(0)
提交回复
热议问题