使用使用捕获返回类型的模板化可调用对象

时间:2013-10-05 03:54:46

标签: c++ templates c++11

有没有办法在类级别使用using来获取可调用模板参数的类型(lambda,可调用类,函数指针)

template <typename FunctionType>
class SomeClass {
    using FunctionReturnType = /* extract return type of FunctionType */
};

我和decltype以及result_of混淆了,并给出了一个FunctionType的实例以及我在成员函数中完成的参数,但它似乎在那里应该是在班级一级做到这一点的方法。

1 个答案:

答案 0 :(得分:4)

我不确定你做错了什么,这似乎对我有用:

    template <class FType>
    struct SomeClass
    {
        using FunctionReturnType = 
            decltype(std::declval<FType>()(std::declval<int>()));
    };

    int f(int){return 0;}
    SomeClass<decltype(f)>::FunctionReturnType t = 0;

我记得我刚才在这个网站上找到了这个代码:

    #include <functional>

    template<typename T> 
    struct function_traits_impl;

    template<typename R, typename ...Args> 
    struct function_traits_impl<std::function<R(Args...)> >
    {
        static const std::size_t nargs = sizeof...(Args);

        typedef R result_type;

        template <std::size_t i>
        struct arg
        {
            typedef typename std::tuple_element<i, std::tuple<Args...> >::type type;
        };
    };

    template <class R, class T, class ... Args>
    function_traits_impl<std::function<R(Args...)> > function_traits(R(T::*)(Args...)const)
    {
        return function_traits_impl<std::function<R(Args...)> >();
    }

    template <class R, class T, class ... Args>
    function_traits_impl<std::function<R(Args...)> > function_traits(R(T::*)(Args...))
    {
        return function_traits_impl<std::function<R(Args...)> >();
    }

    template <class R, class ... Args>
    function_traits_impl<std::function<R(Args...)> > function_traits(R(*)(Args...))
    {
        return function_traits_impl<std::function<R(Args...)> >();
    }

您可能会发现它很有用。它用作:

    typedef decltype(function_traits(&f)) f_info;
    static const unsigned num_args = f_info::nargs;
    typedef f_info::arg<0>::type arg_type;
    typedef f_info::result_type result_type;

它允许您在不知道函数先验的情况下获取参数的数量,它们的类型和函数的返回类型。 function_traits为成员函数和自由函数重载,因此它可以同时使用。

我不记得我在哪里找到了这个,但它在某处here附近。