Convert lambda with capture clause stored in std :: function to raw function pointer

Since my last question was, unfortunately, formulated and led to the solution of another problem, and then mine, here I will try to formulate my actual problem in a clear form.

Before we get started as a side element, I integrate the Javascript Engine V8 into my C ++ application. Where all the types in the example come from. And that is also the reason that in the end I need a raw function pointer. But I dwell on this below.

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

In this code, the InvocationCallback is simply a typedef for a function with a signature of 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 lambda expressions have the same signature. Note that Handle<String> compatible with Handle<Value> in this example. It is also given by the Javascript Engine V8.

 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 function above. But I think the lambda expression also stores a reference to the object it refers to. Somehow, the access specified [=] must be implemented. This may cause std::function to fail for a pointer to raw functions.

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

There is no compile-time error or runtime error, but the debugger tells me that this leads to a null pointer. But I need a raw function pointer for further processing. I assume that I could convert the lambda after std::bind using a link or this -pointer.

Update: because of the inability to get state from lambda, this is what I tried. It compiles, but function displayed as 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>(); } 
+4
c ++ lambda binding function-pointers std-function
Apr 01 '13 at 18:11
source share
2 answers

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

Search around Stack for a "member function for the callback" and you will get a view (basically, you want to use the member function, operator() , as the callback).

+4
Apr 01 '13 at 20:32
source share

You can convert an exciting lambda / functor to a function pointer, but you have to be careful:

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

0
Feb 05 '15 at 7:24
source share



All Articles