【问题标题】:How do I get the argument types of a function pointer in a variadic template class?如何在可变参数模板类中获取函数指针的参数类型?
【发布时间】:2012-02-22 07:38:41
【问题描述】:

这是这个问题的后续:Generic functor for functions with any argument list

我有这个函子类(完整代码见上面的链接):

template<typename... ARGS>
class Foo
{
    std::function<void(ARGS...)> m_f;
public:
    Foo(std::function<void(ARGS...)> f) : m_f(f) {}
    void operator()(ARGS... args) const { m_f(args...); }
};

operator() 中,我可以使用in Stroustrup's C++11 FAQ 所述的递归“剥离”函数轻松访问args...

我的问题是:我想在构造函数中访问 f 的参数类型,即ARGS...。显然我无法访问值,因为到目前为止还没有,但是参数类型列表不知何故被埋在f 中,不是吗?

【问题讨论】:

    标签: c++ c++11 function-pointers functor variadic-templates


    【解决方案1】:

    你可以写function_traits类如下图,来发现参数类型、返回类型和参数个数:

    template<typename T> 
    struct function_traits;  
    
    template<typename R, typename ...Args> 
    struct function_traits<std::function<R(Args...)>>
    {
        static const size_t nargs = sizeof...(Args);
    
        typedef R result_type;
    
        template <size_t i>
        struct arg
        {
            typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
        };
    };
    

    测试代码:

    struct R{};
    struct A{};
    struct B{};
    
    int main()
    {
       typedef std::function<R(A,B)> fun;
    
       std::cout << std::is_same<R, function_traits<fun>::result_type>::value << std::endl;
       std::cout << std::is_same<A, function_traits<fun>::arg<0>::type>::value << std::endl;
       std::cout << std::is_same<B, function_traits<fun>::arg<1>::type>::value << std::endl;
    } 
    

    演示:http://ideone.com/YeN29

    【讨论】:

    • 谢谢@Nawaz,工作至今。尽管如此,还是想从这个解决方案中提取“魔法”并将其放入我的代码中。我想 typename std::tuple_element>::type 是它发生的地方......我该如何做到这一点而不必声明另一个结构
    • @steffen:在定义另一个也可以在其他情况下使用的结构时,您有什么问题吗?此外,将所有代码放在一个类中也不是一个好主意。尝试将代码分成小的工作单元。
    • @steffen:它会起作用的。你一定做错了什么。最好在 www.ideone.com 上发布代码,以便我自己看到错误
    • @steffen:问题是当你使用ARG...时,你需要使用typenametemplate关键字来区分情况。所以你需要写typename function_traits&lt;fun_vararg&gt;::template arg&lt;0&gt;::type,而不是function_traits&lt;fun_vararg&gt;::arg&lt;0&gt;::type。现在看看它的工作原理:ideone.com/bysFS
    • @Nawaz hm,Wayback Machine 在检索您死掉的“演示”链接的内容方面没有任何帮助。 :(
    猜你喜欢
    • 2016-07-23
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多