找出函数,lambda或函数的返回类型 [英] Finding out the return type of a function, lambda or function

查看:88
本文介绍了找出函数,lambda或函数的返回类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这似乎是在这个问题。但那一个是2011年的答案,我正在寻找一个一般情况:lambdas,常规函数和函子。并且,如果可能,通过最现代的c ++语言添加。 (注意: g ++ -std = c ++ 1y test.cpp )。

This seems to be solved for the case of lambdas in this question. But that one is a 2011 answer and I'm looking for a general case: lambdas, regular functions, and functors. And, if possible, by means of the most modern c++ language additions. (Note: g++ -std=c++1y test.cpp).

或lambda),我试图找出它的返回类型是什么。例如,声明一个变量(简化情况)。

So, given a function (or a lambda), I'm trying to find out what its return type is. For instance, to declare a variable (simplified case).

using namespace std;

template<typename F>
void test (F h) {
  // any of the following should be equivalent to int a; int b; int c;
  decltype(h) a; // <<<<< wrong
  result_of(h) b; // <<<<<< wrong
  result_of<decltype(h)> c; // <<<<<< wrong
}

int a_function (int i)  { 
  return 2*i; 
}

int main ()  {
  test (a_function);
}

感谢。

推荐答案

假设:


  1. 只需要返回类型。

  2. 你不知道什么是/将是参数的类型(因此 decltype() std :: result_of< $ $ $ 是一个选项。

  3. 作为参数传递的functor对象不会有重载或通用 c>。

  1. You want only the return type.
  2. You don't know what are/will be the types of arguments (so neither decltype() nor std::result_of<> is an option.
  3. The functor object passed as argument will not have an overloaded or generic operator().

那么你可以使用下面的trait来推断任何函子对象的返回类型:

then you can use the below trait that infers the return type of any functor object:

template <typename F>
struct return_type_impl;

template <typename R, typename... Args>
struct return_type_impl<R(Args...)> { using type = R; };

template <typename R, typename... Args>
struct return_type_impl<R(Args..., ...)> { using type = R; };

template <typename R, typename... Args>
struct return_type_impl<R(*)(Args...)> { using type = R; };

template <typename R, typename... Args>
struct return_type_impl<R(*)(Args..., ...)> { using type = R; };

template <typename R, typename... Args>
struct return_type_impl<R(&)(Args...)> { using type = R; };

template <typename R, typename... Args>
struct return_type_impl<R(&)(Args..., ...)> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...)> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...)> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) &> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) &> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) &&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) &&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) const> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) const> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) const&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) const&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) const&&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) const&&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) volatile> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) volatile> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) volatile&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) volatile&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) volatile&&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) volatile&&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) const volatile> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) const volatile> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) const volatile&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) const volatile&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args...) const volatile&&> { using type = R; };

template <typename R, typename C, typename... Args>
struct return_type_impl<R(C::*)(Args..., ...) const volatile&&> { using type = R; };

template <typename T, typename = void>
struct return_type
    : return_type_impl<T> {};

template <typename T>
struct return_type<T, decltype(void(&T::operator()))>
    : return_type_impl<decltype(&T::operator())> {};

template <typename T>
using return_type_t = typename return_type<T>::type;

测试:

#include <type_traits>

template <typename F>
void test(F h)
{
    static_assert(std::is_same<return_type_t<F>, int>{}, "!");

    return_type_t<F> i = 1;
}

int function(int i) { return 2*i; }

int c_varargs_function(...) { return 1; }

struct A
{
    int mem_function(double, float) { return 1; } 
};

int main()
{
    // Function
    test(function);

    // C-style variadic function
    test(c_varargs_function);

    // Non-generic lambda
    test([](int i) { return 2*i; });

    // Member function
    test(&A::mem_function);
}

DEMO

这篇关于找出函数,lambda或函数的返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆