如何定义一个采用带有 capture 的 lambda 作为参数的函数?

Art*_*out 4 c++ algorithm lambda function-pointers c++11

我有这个函数,如果列表true中的任何元素与给定的匹配,则返回predicate

bool _any(bool (*predicate)(MyStructure), list<MyStructure> arr)
{
    for (int i = 0; i < arr.size(); i++)
    {
        if (predicate(arr.front()))
            return true;
        arr.pop_front();
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

这适用于非常简单的 lambda,但如果给定的 lambda 需要捕获this,那么我会遇到一个错误,我不知道如何修复。

Assert::IsTrue(_any(
    [this](MyStructure t)
    {
        return t._name == "NAME_SEARCHED" &&
            t._type == "TYPE_SEARCHED" &&
            _any([](OtherStruct o) { return o._name == "SEARCHED_2"; }, t._children);
    },
    myList));
Run Code Online (Sandbox Code Playgroud)

错误:

cannot convert argument 1 from 'UTests::<lambda_e8bda0383e9f0c2ae44be631a7424852>' 
to 'bool (__cdecl *)(MyNameSpace::MyStructure)'
Run Code Online (Sandbox Code Playgroud)

(注意:_any也需要OtherStruct定义)。

JeJ*_*eJo 5

您无法将有状态 lambda 转换为函数指针!

问题是,该_any函数需要一个类型化的函数指针,bool (*)(MyStructure) 而不是 lambda函数。如果 lambda 是无捕获的 lambda,则可以将其转换为函数指针。

这意味着,在这里

Assert::IsTrue(_any(
[this](MyStructure t)
//^^^^ ---> capture the "this"
{
   // ...
},
myList));
Run Code Online (Sandbox Code Playgroud)

您正在尝试将 lambda 函数(通过捕获实例)转换为类型化函数指针。这是根本不可能的,因此会出现编译器错误。


我不知道如何解决。

制作_any一个模板函数,以便编译器可以为你进行推演。

template<typename Callable>
bool _any(Callable predicate, std::list<MyStructure> const& arr)
{
   // ...
    return false;
}
Run Code Online (Sandbox Code Playgroud)

或使用std::function,具有某种类型擦除开销

#include <functional> // std::function

bool _any(std::function<bool(MyStructure)> const& predicate
    , std::list<MyStructure> const& arr)
{
   // ...
    return false;
}
Run Code Online (Sandbox Code Playgroud)