c++ - 查询 lambda/函数的参数数量

标签 c++ lambda std-function

我想查询一个 lambda/函数它使用了多少参数。 小(伪)示例代码:

template <class InputIterator, class Predicate>
bool visitAll( InputIterator f, InputIterator l, Predicate p, UserData* d=nullptr)
{
    for(; f != l; ++f)
    {
        if(number_of_arguments(p) == 1)
        {
            if(!p(*f))
                return false;
        }
        else
        {
            if(!p(*f, *d))
                return false;
        }
    }
}

请注意,我要求的函数是 number_of_arguments(...)。 我一直在 Closure 和 std::function 引用资料中搜索,但没有找到有关解决方案的线索。

感谢您的帮助!

最佳答案

显然,您发布的代码没有多大意义,因为无论如何 p(*f)p(*f, *d) 都无法编译.因此,您需要将其拆分为两个模板,然后您可以使用相当简单的 SFINAE 方法测试 Predicate 的参数数量:

template <class InputIterator, class Predicate>
bool visitAll( InputIterator f, InputIterator l, Predicate p, UserData* d=nullptr, 
   decltype(declval<Predicate>()(*declval<InputIterator>()),1) unused = 1)
{
    cout << "1" << std::endl;
    for(; f != l; ++f)
    {
        if(!p(*f))
            return false;
    }
    return true;
}

template <class InputIterator, class Predicate>
bool visitAll( InputIterator f, InputIterator l, Predicate p, UserData* d=nullptr, 
   decltype(declval<Predicate>()(*declval<InputIterator>(), declval<UserData>()),1) unused = 1)
{
    cout << "2" << std::endl;
    for(; f != l; ++f)
    {
        if(!p(*f, *d))
            return false;
    }
    return true;
}

用法:

std::vector<int> a{1,2};
const auto t = [](int x){ return 1;};
const auto t2 = [](int x, UserData y){ return 1;};

UserData d;
visitAll(a.begin(), a.end(), t);
visitAll(a.begin(), a.end(), t2, &d);

当然,您可以使用 std::bind 通过从第二个版本调用第一个版本来避免代码重复。


另一种方法是使用类似于 std::bind 检查它是否获得所需参数数量的代码:

template<typename _Func>
struct noa_helper { 
};

template<typename _Ret, typename... _Args>
struct noa_helper<_Ret (*)(_Args...)> {
    static int noa() { return sizeof...(_Args); }
};

template<class F>
int number_of_arguments(F f) {
    return noa_helper<typename std::decay<F>::type>::noa();
}

void foo();
int bar(int x, int y);
...
std::cout << number_of_arguments(foo) << std::endl; // prints 0
std::cout << number_of_arguments(bar) << std::endl; // prints 2

这仅适用于实际函数,不适用于 lambda 表达式,也不适用于 std::function,尽管可能更多的模板魔法可以使其适用于后两个类别。

关于c++ - 查询 lambda/函数的参数数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36287291/

相关文章:

c++ - 为什么 remove_if( ..., lambda ) 表达式需要赋值运算符?

ruby-on-rails - 如何将旧的 lambda 语法转换为新的 lambda 文字语法

Java 8 流 API,如何使用多个列表字段将列表收集到对象

c++ - 如何调用对象在函数内部的类方法

c++ - 在编译时捕获 std::function 分配

c++ - 使用贝塞尔曲线创建圆角立方体?

c++ - 位图显示不正确

c++ - 什么是boost log,如何获取以及如何构建

c++ srand 不给出相同的随机数序列

C++ 绑定(bind)回调到一个类