gpt4 book ai didi

c++ - 将捕获的 lambda 包装为模板函数中的函数指针

转载 作者:搜寻专家 更新时间:2023-10-31 02:01:59 24 4
gpt4 key购买 nike

我有以下代码,它将捕获的 lambda 转换为非捕获的 lambda,因此它可以作为函数指针传递给 C 风格的 API:

(统计这里是一个简单的结构)

auto closure = [&](Statistics stats) {
setStats(stats);
};

auto wrapper = +[](Statistics stats, void* userdata) {
(*static_cast<decltype(closure)*>(userdata))(stats);
};

call_callback (wrapper, &closure);

因为这个模式会在我的应用程序中使用几次,所以我想将它概括为一个模板函数:

template <typename T>
auto wrap_closure(std::function<void(T)> closure) -> void(*)(T, void*)
{
auto wrapper = +[](T data, void* userdata) {
(*static_cast<decltype(closure)*>(userdata))(data);
};
return wrapper;
}

但是,如果我尝试使用它,我会在 std::function 中得到一个 EXC_BAD_ACCESS 异常:

auto closure = [&](Statistics stats) {
setStats(stats);
};

call_callback (wrap_closure<Statistics> (closure), &closure);

我不应该在这里使用 std::function 吗?

最佳答案

问题是 decltype(closure)里面wrap_closurestd::function<void(Statistics)> , 而原来的 closure您传入的地址是 lambda。它们不是同一类型,因此 static_cast通过void *有未定义的行为。

您可以通过任何一种方式修复它,要么保留 std::function但要确保双方同意:

std::function<void(Statistics)> f = closure;
call_callback (wrap_closure(f), &f);

...如您所见,它非常脆弱,或者摆脱 std::function并使用 closure 的类型原样:

template <typename... T, typename Callable>
auto wrap_closure(Callable const &) -> void(*)(T..., void*)
{
return +[](T... data, void* userdata) {
(*static_cast<Callable*>(userdata))(data...);
};
}

// Usage
call_callback (wrap_closure<Statistics>(closure), &closure);

Variadic 盐和胡椒免费。

关于c++ - 将捕获的 lambda 包装为模板函数中的函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58203640/

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