C++ lambda 捕获作为函数指针

2021-12-12 00:00:00 lambda function-pointers c++ c++11

我在玩 C++ lambdas 和它们到函数指针的隐式转换.我的起始示例是将它们用作 ftw 函数的回调.这按预期工作.

I was playing with C++ lambdas and their implicit conversion to function pointers. My starting example was using them as callback for the ftw function. This works as expected.

#include <ftw.h>
#include <iostream>

using namespace std;

int main()
{
    auto callback = [](const char *fpath, const struct stat *sb,
        int typeflag) -> int {
        cout << fpath << endl;
        return 0;
    };

    int ret = ftw("/etc", callback, 1);

    return ret;
}

修改后使用捕获:

int main()
{

    vector<string> entries;

    auto callback = [&](const char *fpath, const struct stat *sb,
        int typeflag) -> int {
        entries.push_back(fpath);
        return 0;
    };

    int ret = ftw("/etc", callback, 1);

    for (auto entry : entries ) {
        cout << entry << endl;
    }

    return ret;
}

我收到编译器错误:

error: cannot convert ‘main()::<lambda(const char*, const stat*, int)>’ to ‘__ftw_func_t {aka int (*)(const char*, const stat*, int)}’ for argument ‘2’ to ‘int ftw(const char*, __ftw_func_t, int)’

经过一些阅读.我了解到使用捕获的 lambdas不能隐式转换为函数指针.

After some reading. I learned that lambdas using captures can't be implicitly converted to function pointers.

是否有解决方法?它们不能隐式"转换的事实是否意味着它们可以显式"转换?(我尝试铸造,但没有成功).修改工作示例以便我可以使用 lambda 将条目附加到某个对象的干净方法是什么?.

Is there a workaround for this? Does the fact that they can't be "implicitly" converted mean s that they can "explicitly" converted? (I tried casting, without success). What would be a clean way to modify the working example so that I could append the entries to some object using lambdas?.

推荐答案

由于捕获 lambdas 需要保留一个状态,因此并没有真正简单的解决方法",因为它们不只是普通的职能.函数指针的要点在于它指向一个单一的全局函数,并且这个信息没有状态的空间.

Since capturing lambdas need to preserve a state, there isn't really a simple "workaround", since they are not just ordinary functions. The point about a function pointer is that it points to a single, global function, and this information has no room for a state.

最接近的解决方法(基本上丢弃状态)是提供某种类型的全局变量,该变量可从您的 lambda/函数访问.例如,您可以创建一个传统的函子对象,并为其提供一个静态成员函数,该函数引用某个唯一(全局/静态)实例.

The closest workaround (that essentially discards the statefulness) is to provide some type of global variable which is accessed from your lambda/function. For example, you could make a traditional functor object and give it a static member function which refers to some unique (global/static) instance.

但这有点违背了捕获 lambda 的全部目的.

But that's sort of defeating the entire purpose of capturing lambdas.

相关文章