c – 传递lambda函数作为参数时没有匹配的函数错误

前端之家收集整理的这篇文章主要介绍了c – 传递lambda函数作为参数时没有匹配的函数错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个数字列表.

我试图过滤列表,只保留正数.

我试图通过传递lambda作为参数来做到这一点.

我想知道为什么我会出现函数不匹配错误.

#include <vector>
#include <algorithm>
#include <functional>

template<typename T>
std::vector<T> keep(
        const std::vector<T> &original,std::function<bool(const T&)> useful)
{
    std::vector<T> out;
    for(T item:original)
    {
        if(useful(item))
            out.push_back(item);
    }
    return out;
}

int main()
{
    std::vector<int> a={4,6,2,-5,3,-8,13,-11,27};
    a=keep(a,[](const int& x)->bool{return x>0;});
    for(int y:a)
    {
        std::cout<<y<<std::endl;
    }
    return 0;
}

这是错误消息:

error: no matching function for call to ‘keep(std::vector<int>&,main()::<lambda(const int&)>)’
     a=keep(a,[](const int& x)->bool{return x>0;});
                                                 ^

解决方法

更改功能保持
template<typename T,typename Func>
std::vector<T> keep(const std::vector<T> &original,Func useful)
{
    // code as usual
}

Live example.

这适用于以下任何一个有用的参数:

> lambda
> std :: function
> functor
>函数指针

the documentation

The lambda expression constructs an unnamed prvalue temporary object of unique unnamed non-union non-aggregate type,known as closure type.

这意味着具有相同代码的两个lambdas将生成两个不同的类型对象.

auto f1 = [](int) { return true; };
auto f2 = [](int) { return false; };
f2 = f1;                               // error: no viable '='

但是,这两个都可以隐式转换为相应的std :: function类型:

std::function<bool(int)> fn = f1;
fn = f2;

但那么为什么它不适合你的情况呢?这是因为模板类型扣除.改变保持

template<typename T>
std::vector<T> keep(const std::vector<T> &original,std::function<bool(const int &)> useful)
// no type deduction for std::function's template,explicitly mentioned

将使您的示例编译而不在调用站点进行任何强制转换.

但是,尝试将其与std :: function< T>匹配因为模板类型扣除不考虑任何转换,所以不起作用.模板参数推导查找精确类型匹配.在这个阶段,隐含的转换并不重要.您必须将它显式地转换为匹配的std :: function作为Atomic_alarm注释.就像约瑟夫在How to convert a lambda to an std::function using templates所说:

Template type deduction tries to match the type of your lambda function to the std::function<T> which it just can’t do in this case – these types are not the same. Template type deduction doesn’t consider conversions between types.

在替代解决方案中,发生的事情是这样的:

auto f = [](int i) { return (i >= 0); }

这里的f类型不是std :: function,而是推导出一些未命名的类型,就像上面的模板参数Func一样.

如果您仍然希望以std :: function方式执行此操作,请参阅this answer,它使用其他模板间接方式执行此操作.有关详细信息,请参见this answerthis post.

猜你在找的C&C++相关文章