gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 12:02:13 39 4
gpt4 key购买 nike

我在玩 C++ lambda 及其到函数指针的隐式转换。我的开始示例是使用它们作为 ftw 函数的回调。这按预期工作。

#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 不能隐式转换为函数指针。

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

最佳答案

我刚刚遇到了这个问题。

代码在没有 lambda 捕获的情况下可以正常编译,但是 lambda 捕获会出现类型转换错误。

C++11 的解决方案是使用 std::function (编辑:另一个不需要修改函数签名的解决方案显示在此示例之后)。您还可以使用 boost::function (实际上运行速度要快得多)。示例代码 - 更改为可以编译,使用 gcc 4.7.1:

编译
#include <iostream>
#include <vector>
#include <functional>

using namespace std;

int ftw(const char *fpath, std::function<int (const char *path)> callback) {
return callback(fpath);
}

int main()
{
vector<string> entries;

std::function<int (const char *fpath)> callback = [&](const char *fpath) -> int {
entries.push_back(fpath);
return 0;
};

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

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

return ret;
}

编辑:当我遇到无法修改原始函数签名但仍需要使用 lambdas 的遗留代码时,我不得不重新审视这一点。不需要修改原函数的函数签名的解决方案如下:

#include <iostream>
#include <vector>
#include <functional>

using namespace std;

// Original ftw function taking raw function pointer that cannot be modified
int ftw(const char *fpath, int(*callback)(const char *path)) {
return callback(fpath);
}

static std::function<int(const char*path)> ftw_callback_function;

static int ftw_callback_helper(const char *path) {
return ftw_callback_function(path);
}

// ftw overload accepting lambda function
static int ftw(const char *fpath, std::function<int(const char *path)> callback) {
ftw_callback_function = callback;
return ftw(fpath, ftw_callback_helper);
}

int main() {
vector<string> entries;

std::function<int (const char *fpath)> callback = [&](const char *fpath) -> int {
entries.push_back(fpath);
return 0;
};
int ret = ftw("/etc", callback);

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

return ret;
}

关于将捕获作为函数指针的 C++ lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7852101/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com