将lambda函数作为参数传递时,没有匹配的函数错误 [英] No matching function error when passing lambda function as argument

查看:183
本文介绍了将lambda函数作为参数传递时,没有匹配的函数错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数字列表。

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

I am trying to filter the list and only keep the positive numbers.

我正在尝试通过传递lambda作为参数来做到这一点。

I am trying to do it by passing a lambda as an argument.

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

I wonder why I get function mismatch error.

#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
}

在线示例

这与有用是其中任何一个的论点一起起作用:

This works with an argument to useful being any one of these:


  • lambda

  • std :: function

  • functor

  • 函数指针

  • lambda
  • std::function
  • functor
  • function pointer

来自文档


lambda表达式构造一个未命名的prvalue临时对象

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

这表示具有相同代码的两个lambda会被称为闭包类型。产生两个

This means that two lambdas with the same code, would generate two different typed objects.

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

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

However, both of these are implicitly convert-able to the corresponding std::function types:

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

但是为什么在您的情况下不起作用?这是由于模板类型推导。将保留更改为

But then why doesn't it work in your case? This is because of template type deduction. Changing keep to

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

将使您的示例在调用方站点上无需任何强制转换即可编译。

will make your example compile without any cast at the caller site.

但是,尝试将其与 std :: function< T> 匹配,因为模板类型推导不考虑任何转换。模板自变量推导寻找完全匹配的类型。在此阶段,隐式转换无关紧要。您必须将其显式转换为匹配的 std :: function 作为 Atomic_alarm 注释。就像约瑟夫(Joseph)在如何使用模板将Lambda转换为std :: function

However, trying to match it against std::function<T> won't work since template type deduction doesn't consider any conversion. Template argument deduction looks for exact type matches. Implicit conversions don't matter at this stage. You've to explicitly cast it to a matching std::function as Atomic_alarm comments. Like Joseph says in How to convert a lambda to an std::function using templates:


模板类型推导尝试将您的lambda函数的类型与 std :: function< T> 匹配在这种情况下就是做不到-这些类型不一样。模板类型推导不考虑类型之间的转换。

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.

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

While in the alternative solution what happens is something like this:

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

此处的 f 类型不是 std :: function ,但是像上面的模板参数 Func 一样推导出一些未命名的类型。

The type of f here is not std::function but some unnamed type deduced like it would for the template parameter Func above.

如果仍然要使用 std :: function 方法,请参见此答案,其中包含一个额外的间接模板功能。参见此答案此信息以获取相关详细信息。

If you still want to do it the std::function way, see this answer which does it with an additional template indirection. See this answer and this post for related details.

这篇关于将lambda函数作为参数传递时,没有匹配的函数错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆