我想知道是否可以“模式匹配”函数和可调用对象来提取(在编译时)函数的参数个数。 换句话说,我想创建一个名为 count_arg 的元函数 返回传递函数的参数个数。
考虑以下代码:
#include <iostream>
#include <functional>
#include <type_traits>
#define LIFT_FUN(f) decltype(f)
template<typename T>
struct count_arg : public count_arg<decltype(&T::operator())>
{
};
template<typename R, typename ...Args>
struct count_arg<R(Args...)>
{
static const size_t value = sizeof...(Args);
};
template <typename C, typename R, typename... Args>
struct count_arg<R(C::*)(Args...) const>
{
static const size_t value = sizeof...(Args);
};
template<typename R, typename ...Args>
struct count_arg<R(*)(Args...)>
{
static const size_t value = sizeof...(Args);
};
template<typename R, typename ...Args>
struct count_arg<R(&)(Args...)>
{
static const size_t value = sizeof...(Args);
};
template <typename T>
struct show_type;
template <typename F>
decltype(auto) flip(F f)
{
return [f](auto a, auto b){
return f(b, a);
};
}
int minus(int a, int b, int c)
{
return a - b + c;
}
struct Minus
{
int operator()(int a, int b) const
{
return a - b;
}
};
int main()
{
int a{5}, b{3};
auto g = [](int a, int b){
return a - b;
};
auto fmin = flip(g);
std::cout << minus(a, b, 0) << std::endl;
std::cout << fmin(a, b) << std::endl;
std::cout << "minus arity:" << count_arg<LIFT_FUN(minus)>::value << std::endl;
std::cout << " g arity:" << count_arg<LIFT_FUN(g)>::value << std::endl;
std::cout << "Minus arity:" << count_arg<LIFT_FUN(Minus{})>::value << std::endl;
}
此示例有效,但如果我尝试 fmin :
std::cout << " fmin arity:" << count_arg<LIFT_FUN(fmin)>::value << std::endl;
(使用g ++ 4.9.2:g ++ flip.cpp -o flip -std = c ++ 14) 我收到了这个错误:
flip.cpp: In instantiation of ‘struct count_arg<flip(F) [with F = main()::<lambda(int, int)>]::<lambda(auto:1, auto:2)> >’:
flip.cpp:83:61: required from here
flip.cpp:9:8: error: decltype cannot resolve address of overloaded function
struct count_arg : public count_arg<decltype(&T::operator())>
^
flip.cpp: In function ‘int main()’:
flip.cpp:83:36: error: ‘value’ is not a member of ‘count_arg<flip(F) [with F = main()::<lambda(int, int)>]::<lambda(auto:1, auto:2)> >’
std::cout << " fmin arity:" << count_arg<LIFT_FUN(fmin)>::value << std::endl;
有什么想法吗?
修改
根据Vittorio的建议,我尝试了get_arity实现(Get function arity from template parameter):
std::cout << " g arity:" << get_arity<decltype(g)>::value << std::endl;
std::cout << "fmin arity:" << get_arity<decltype(fmin)>::value << std::endl;
但我仍然遇到 fmin 的问题。 如果我以这种方式更改翻转(返回的lambda不是更通用的):
template <typename F>
decltype(auto) flip(F f)
{
return [f](int a, int b){
return f(b, a);
};
}
我的代码编译......
所以我现在的问题是我必须找到一种方法从 通用lambdas 中提取数字og参数。 有什么想法吗?