C++ 查找函数、lambda或函数的返回类型

C++ 查找函数、lambda或函数的返回类型,c++,c++11,C++,C++11,这一点似乎在年的lambdas案件中得到了解决。但这是2011年的答案,我在寻找一个一般情况:lambdas、正则函数和函子。如果可能的话,通过最新的C++语言添加。(注:g++-std=c++1y test.cpp) 所以,给定一个函数(或lambda),我试图找出它的返回类型。例如,声明一个变量(简化的大小写) 使用名称空间std; 模板 孔隙试验(F h){ //下列任何一项应等同于int a;int b;int c; decltype(h)a;//std::result\u of::ty

这一点似乎在年的lambdas案件中得到了解决。但这是2011年的答案,我在寻找一个一般情况:lambdas、正则函数和函子。如果可能的话,通过最新的C++语言添加。(注:
g++-std=c++1y test.cpp

所以,给定一个函数(或lambda),我试图找出它的返回类型。例如,声明一个变量(简化的大小写)

使用名称空间std;
模板
孔隙试验(F h){
//下列任何一项应等同于int a;int b;int c;
decltype(h)a;//
std::result\u of::type a;

(取自。)

假设:

  • 您只需要返回类型
  • 您不知道参数的类型(因此
    decltype()
    std::result\u的
  • 作为参数传递的函子对象将没有重载或泛型的
    运算符()
  • 然后,您可以使用以下特征推断任何函子对象的返回类型:

    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;
    
    模板
    结构返回\u类型\u impl;
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回\u type\u impl{using type=R;};
    模板
    结构返回类型
    :return_type_impl{};
    模板
    结构返回类型
    :return_type_impl{};
    模板
    使用return\u type\u t=typename return\u type::type;
    
    测试:

    #包括
    模板
    孔隙试验(F h)
    {
    静态断言(std::is_same{},“!”);
    返回类型i=1;
    }
    int函数(inti){返回2*i;}
    int c_varargs_函数(…){return 1;}
    结构A
    {
    int mem_函数(双精度,浮点){return 1;}
    };
    int main()
    {
    //作用
    测试(功能);
    //C型变量函数
    测试(c_varargs_函数);
    //非泛型lambda
    测试([](int i){返回2*i;});
    //成员函数
    测试(&A::mem_函数);
    }
    

    当你有两个重载的h函数:
    inth(int)
    float h(float)
    ,你期望(h)
    结果返回什么?@Zadirion很好。但在我的问题中,要么只有一个h(),要么实际上是h()将是另一个函数的输入参数。为什么要在不知道如何调用函数的情况下查找函数的返回值?这有何用处?或者您知道如何调用它?是否无法避免您的特性(或使用某些
    std
    功能将其压缩)“?@Walter。应该有。由于特征不再是样板代码,它应该简单地存在
    return\u type
    与它存在的方式相同
    decltype(a)
    @Walter,因为它的功能是有限的(正如我在开头列出的),我怀疑这种特征是否会被引入标准库。”(目前没有等效的参数,您需要知道要使用的参数类型,并利用
    decltype(func(1,2,3))
    std::result\u of\u t
    。还需要在不使用宏的帮助下对其进行压缩definitions@Walter除了有限的功能外,它的用例非常狭窄。我不敢说“无用”在C++中,应该重载:你应该知道在你问它将返回什么之前,你将如何使用一个类型。我仍然发现,有这么多人喜欢C++这样的答案,以及有多少人喜欢这些使暴行成为可能的语言特征。
    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);
    }