如何获取`std::function`的参数个数?

16

能否获得 std::function 的参数数量?类似于 NumOfArgument<...>::value 这样的东西。

例如,NumOfArgument<function<int(int, int)> >::value 应该是2。


1
你为什么要这样做?有具体的原因吗? - Invictus
1个回答

48

我认为 std::function 本身并没有提供那个功能。但您可以自己实现,如下:

template<typename T> 
struct count_arg;

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

测试代码:

typedef std::function<int(int, int)> fun;
std::cout << count_arg<fun>::value << std::endl; //should print 2

参考这个: 在线演示


同样地,您可以加入更多功能,例如:

template<typename T> 
struct function_traits;     //renamed it!

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;
    };
};

现在,您可以使用 const 索引获取每个参数类型,如下所示:

std::cout << typeid(function_traits<fun>::arg<0>::type).name() << std::endl;
std::cout << typeid(function_traits<fun>::arg<1>::type).name() << std::endl;
std::cout << typeid(function_traits<fun>::arg<2>::type).name() << std::endl;

演示链接

它输出类型的重载名称!


5
+1:一旦你掌握了可变参数模板,它就变得非常简单。O__O; - Klaim
1
不错的解决方案...我之前不知道 sizeof...(Args) 是一个正确的语法!因为通常 sizeof() 只处理数据类型的大小而不是元素数量,所以 sizeof() 对于 Args 有特殊的含义吗? - iammilind
4
sizeof...(T)是用于获取参数包T的大小的特殊语法。它与sizeof(T)无关(§5.3.3/5,§14.5.3/7)。 - kennytm
一个小问题:为了与 struct arg 保持一致,nargs 应该是 size_t 类型... 而且因为它无论如何都不可能为负。 - Matthieu M.
1
很棒的想法。我将其标记为正确答案。非常感谢。不过,我认为function_traits应该被包含在标准中。 - Yun Huang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接