本文介绍了拉姆达转换与存储在的std ::函数原始函数指针捕捉条款的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我的last最近的问题不幸的措辞,并导致解决另一个问题,然后我的,在这里我将尝试制定我的实际问题,以明确的方式。

在我们开始之前,作为一个旁注,我整合了JavaScript引擎V8到我的C ++应用程序。这就是在本例中所有类型从何而来。而这也是我需要在最后一个原函数指针的事实的原因。但我细说了下文。

从类中我需要通过一个Lambda前pression与捕获子句 [=] 作为类型参数 STD ::功能给另一个函数,并将其转换为原始函数指针那里。

在此code, InvocationCallback 简直就是与签名功能的typedef 处理<价值>(参数常量和放大器;)

 的typedef处理< VALUE> (* InvocationCallback)(参数常量和放大器;);无效绑定(字符串名称,功能和LT;处理< VALUE>(参数常量和放大器;)>功能)
{
    InvocationCallback *功能= Function.target< InvocationCallback>();
}

所有的lambda前pressions具有相同的签名,太。需要注意的是处理<弦乐> 是兼容处理<价值> 在这个例子中。它是由JavaScript引擎V8给出了。

 绑定(名,[=](常量参数和放大器;参数) - >处理< VALUE> {
    手柄<串GT;结果=字符串::新(名称()c_str());
    返回结果;
});

C ++允许我到这个拉姆达为的std ::功能传递给函数的上方。但我想一个lambda前pression还存储参考对象是指。不知怎的,由指定的访问[=] 必须实现。这可能是铸造的原因的std ::功能来的原始函数指针失败。

  InvocationCallback *功能= Function.target< InvocationCallback>();

有既不是一个编译时错误,也不是一个运行时错误,但调试器告诉我,这导致空指针。但我需要做进一步处理原始函数指针。我想我可以在的std ::绑定拉姆达转换ING引用或这个终场第一。

更新:由于这似乎是不可能得到国家走出拉姆达的,这就是我试过了。它编译但函数出来是一个空指针。

 绑定(名,对此,[](基*的对象,常量参数和放大器;参数) - >处理< VALUE> {
    返回V8 ::字符串::新(((*派生)对象) - 方式>名称()c_str());
});无效绑定(字符串名称,模块*对象,功能和LT;处理< VALUE>(模块*,参数常量和放大器;)>功能)
{
    功能<&手柄LT; VALUE>(参数常量和放大器;)>方法=的std ::绑定(函数,对象的std ::占位符:: _ 1);
    InvocationCallback *功能= method.target< InvocationCallback>();}


解决方案

您不能,因为它可以捕获一个lambda是的闭合的,所以它有状态(它是与实例变量的对象)。一个函数指针没有状态。因此,你不能没有做到这一点无论1)您所使用的API需要的函数指针也可以让你通过,你传递状态的用户数据参数,或者2)存储在一个全局变量或东西的状态。

周围堆栈溢出搜索成员函数回调,你会得到一个想法(基本上,你是想用一个成员函数时,运算符(),作为回调)。

Since my last recent question was unfortunately worded and resulted in a solution to another problem then mine, here I will try to formulate my actual problem in a clear way.

Before we start, as a sidenote, I am integrating the Javascript Engine V8 into my C++ application. That's where all the types in the example come from. And that's also the reason for the fact that I need a raw function pointer in the end. But I elaborate on this below.

From inside a class I need to pass a lambda expression with the capture clause [=] as parameter of the type std::function to another function and cast it to a raw function pointer there.

In this code, InvocationCallback is simply a typedef for a function with the signature Handle<Value>(Arguments const &).

typedef Handle<Value> (*InvocationCallback)(Arguments const &);

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

All the lambda expressions have the same signature, too. Note that Handle<String> is compatible to Handle<Value> in this example. It's given by the Javascript Engine V8, too.

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

C++ allows me to pass this lambda as std::function to the function above. But I guess a lambda expression also stores a reference to object it refers. Somehow the access specified by [=] must be realized. That might be the reasons that casting the std::function to a raw function pointer fails.

InvocationCallback* function = Function.target<InvocationCallback>();

There is neither a compile time error nor a runtime error but the debugger tells me that it results in a null pointer. But I need the raw function pointer for further processing. I guess I could convert the lambda after std::binding the reference or this-pointer first.

Update: Since it seems to be impossible to get the state out of the lambda, this is what I tried. It compiles but function come out to be a null pointer.

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>();

}
解决方案

You can't, because a lambda which captures is a closure, so it has state (it is an object with instance variables). A function pointer has no state. Thus, you cannot do this without either 1) the API you are using that requires the function pointer also allows you to pass a user data argument where you pass the state, or 2) storing the state in a global variable or something.

Search around Stack Overflow for "member function to callback" and you will get an idea (basically, you are wanting to use a member function, the operator(), as a callback).

这篇关于拉姆达转换与存储在的std ::函数原始函数指针捕捉条款的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 01:14