给出签名的模板功能
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()
的给出的正确方法是什么?
答案 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)
之类的情况下推导函数引用类型(请注意,附加括号)。