C ++从函数签名中提取参数

时间:2019-03-01 23:44:01

标签: c++ templates

给出签名的模板功能

template <typename F>
void fn(F f);

如果给F提供了可调用函数,我想提取给定函数签名fn()的参数包。

在以下示例中,我无法在foo0()foo1()中做到这一点(简化为单个参数而不是参数包):

foo2()

请参见live示例。

如果#include <type_traits> template <typename Sig> struct argument_of; template <typename R, typename Arg> struct argument_of<R(Arg)> { typedef Arg type; }; void bar(int); void foo0() { static_assert(std::is_same<int, typename argument_of<decltype(bar)>::type>::value, "!"); } template <typename F> void foo1(F) { static_assert(std::is_same<int, typename argument_of<F>::type>::value, "!"); } template <typename F> void foo2(F f) { static_assert(std::is_same<int, typename argument_of<decltype(f)>::type>::value, "!"); } int main() { foo0(); foo1(bar); foo2(bar); } 的调用样式保持上面示例中fn()foo1()的给出的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您只需要专门化即可处理函数指针类型:

template <typename Sig> struct argument_of;
template <typename R, typename Arg> struct argument_of<R(Arg)> { typedef Arg type; };
template <typename R, typename Arg> struct argument_of<R(*)(Arg)> { typedef Arg type; };

这是一个很小的区别,我希望我能正确理解术语,但是符号 bar是类型为{{的非重载 function 1}},而变量 void(int)(或未命名的f参数)是类型为F函数指针。 C ++中的变量和函数本质上是不同的,而类型系统具有这种区别。

还值得注意的是,您可能希望专门研究的另一个变体是功能参考,它看起来像void(*)(int)。可以在诸如void(&)(int)decltype(*f)之类的情况下推导函数引用类型(请注意,附加括号)。