首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将存储在std::function中的带有capture子句的lambda转换为原始函数指针

将存储在std::function中的带有capture子句的lambda转换为原始函数指针
EN

Stack Overflow用户
提问于 2013-04-02 02:11:27
回答 2查看 6.6K关注 0票数 8

由于我的last recent question的措辞很不幸,导致了另一个问题的解决方案,而不是我的问题,在这里,我将尝试以一种清晰的方式来阐述我的实际问题。

在开始之前,作为附注,我将把Javascript引擎V8集成到我的C++应用程序中。这就是示例中所有类型的来源。这也是我最终需要一个原始函数指针的原因。但我将在下面详细说明这一点。

在类内部,我需要将一个带有capture子句[=]的λ表达式作为std::function类型的参数传递给另一个函数,并将其强制转换为一个原始函数指针。

在这段代码中,InvocationCallback只是一个签名为Handle<Value>(Arguments const &)的函数的类型定义。

代码语言:javascript
复制
typedef Handle<Value> (*InvocationCallback)(Arguments const &);

void Bind(string Name, function<Handle<Value>(Arguments const &)> Function)
{
    InvocationCallback* function = Function.target<InvocationCallback>();
}

所有的lambda表达式也具有相同的签名。请注意,在本例中,Handle<String>Handle<Value>兼容。它也是由Javascript Engine V8提供的。

代码语言:javascript
复制
Bind("name", [=](const Arguments& args) -> Handle<Value>{
    Handle<String> result = String::New(Name().c_str());
    return result;
});

C++允许我将这个lambda作为std::function传递给上面的函数。但我猜lambda表达式也存储了它所引用的对象的引用。必须以某种方式实现[=]指定的访问。这可能是将std::function转换为原始函数指针失败的原因。

代码语言:javascript
复制
InvocationCallback* function = Function.target<InvocationCallback>();

既没有编译时错误,也没有运行时错误,但是调试器告诉我它会导致空指针。但是我需要原始函数指针来做进一步的处理。我想我可以在std::bind引用或this-pointer之后转换lambda。

更新:由于似乎不可能从lambda中获取状态,这就是我尝试过的。它会编译,但function会变成一个空指针。

代码语言:javascript
复制
Bind("name", this, [](Base* object, const Arguments& args) -> Handle<Value>{
    return v8::String::New(((Derived*)object)->Name().c_str());
});

void Bind(string Name, Module *Object, function<Handle<Value>(Module*, Arguments const &)> Function)
{
    function<Handle<Value>(Arguments const &)> method = std::bind(Function, Object, std::placeholders::_1);
    InvocationCallback* function = method.target<InvocationCallback>();

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-02 04:32:46

你不能,因为一个捕获的lambda是一个闭包,所以它有状态(它是一个带有实例变量的对象)。函数指针没有状态。因此,如果没有1)需要函数指针的API还允许您在传递状态的地方传递用户数据参数,或者2)将状态存储在全局变量或其他变量中,则无法做到这一点。

在Stack Overflow中搜索“要回调的成员函数”,你会得到一个想法(基本上,你想要使用一个成员函数,operator(),作为回调)。

票数 5
EN

Stack Overflow用户

发布于 2015-02-05 15:24:57

您可以将捕获的lambda/functor转换为函数指针,但在执行此操作时需要小心:

https://codereview.stackexchange.com/questions/79612/c-ifying-a-capturing-lambda

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15748961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档