获取C++中返回值的类型

wrw*_*rwt 8 c++ types decltype c++14

假设我们有一个函数f返回某个未知类型的值(让我们调用它T)并将类型的值T作为参数(并且可能还有一些其他参数).如何获得fC++ 14中的返回类型?

如果我们知道知道参数类型(via std::result_of),有办法做到这一点.如果我们知道所有的参数类型除外,是否可能T

例:

template <class F> // F is functor with   T operator()(T a, T b)
class A {
    // Here I want to do
    // T some_function(T some_arg) { ... }
}
Run Code Online (Sandbox Code Playgroud)

Pio*_*cki 10

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;
Run Code Online (Sandbox Code Playgroud)

测试:

#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, "!");
}
Run Code Online (Sandbox Code Playgroud)

DEMO

  • 当然,不适用于任意函子。而且您还应该对普通函数类型进行部分特化。 (2认同)

T.C*_*.C. 5

基于@Piotr S.的优秀答案,对于任意仿函数类型,如果您知道operator()正确的"模式" 只有一个重载,可以这么说,那么您可以这样做:

// 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()));
Run Code Online (Sandbox Code Playgroud)

这将激活重载决策和模板参数推断以确定权限operator().

然后你可以将这两者结合起来:

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;
Run Code Online (Sandbox Code Playgroud)

演示.