Lambda expressions (C# Programming Guide); 11 minutes to read; Contributors. All; In this article. A lambda expression is a block of code (an expression or a statement block) that is treated as an object. It can be passed as an argument to methods, and it can also be returned by method calls.
Is it possible to pass a lambda function as a function pointer? If so, I must be doing something incorrectly because I am getting a compile error.
Consider the following example
![C Member Function To Lambda C Member Function To Lambda](/uploads/1/2/4/9/124981008/357274659.png)
When I try to compile this, I get the following compilation error:
That's one heck of an error message to digest, but I think what I'm getting out of it is that the lambda cannot be treated as a
Deduplicatorconstexpr
so therefore I cannot pass it as a function pointer? I've tried making x
const as well, but that doesn't seem to help.36.3k66 gold badges5252 silver badges9191 bronze badges
CoryKramerCoryKramer75.9k1212 gold badges9595 silver badges148148 bronze badges
7 Answers
A lambda can only be converted to a function pointer if it does not capture, from the draft C++11 standard section
5.1.2
[expr.prim.lambda] says (emphasis mine):The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.
Note, cppreference also covers this in their section on Lambda functions.
So the following alternatives would work:
and so would this:
and as 5gon12eder points out, you can also use
cbuchartstd::function
, but note that std::function
is heavy weight, so it is not a cost-less trade-off.5,99155 gold badges2424 silver badges5353 bronze badges
Shafik YaghmourShafik Yaghmour129k2323 gold badges340340 silver badges563563 bronze badges
Shafik Yaghmour's answer correctly explains why the lambda cannot be passed as a function pointer if it has a capture. I'd like to show two simple fixes for the problem.
- Use
std::function
instead of raw function pointers.This is a very clean solution. Note however that it includes some additional overhead for the type erasure (probably a virtual function call). - Use a lambda expression that doesn't capture anything.Since your predicate is really just a boolean constant, the following would quickly work around the current issue. See this answer for a good explanation why and how this is working.
18.7k22 gold badges2929 silver badges7070 bronze badges
I know this a little bit old..
But i wanted to add:
Lambda expression (even captured ones) can be handled as a function pointer!
It is tricky because an Lambda expression is not a simple function. It is actually an object with an operator().
When you are creative, you can use this! Think of an 'function' class in style of std::function. If you save the object!
You also can use the function pointer.
To use the function pointer, you can use the following:
To build a class that can start working like a 'std::function' i will just do short example. First you need a class/struct than can store object and function pointer also you need an operator() to execute it:
With this you can now run captured, noncaptured lambdas, just like you are using the original:
This code works with VS2015Hope it helps : )
Greets!
Edit: removed needles template FP, removed function pointer parameter, renamed to lambda_expression
Update 04.07.17:
NoxxerNoxxer
Capturing lambdas cannot be converted to function pointers, as this answer pointed out.
However, it is often quite a pain to supply a function pointer to an API that only accepts one. The most often cited method to do so is to provide a function and call a static object with it.
This is tedious. We take this idea further and automate the process of creating
wrapper
and make life much easier.And use it as
This is essentially declaring an anonymous function at each occurrence of
fnptr
.Note that invocations of
Passer ByPasser Byfnptr
overwrite the previously written callable
given callables of the same type. We remedy this, to a certain degree, with the int
parameter N
.10.9k44 gold badges2626 silver badges6464 bronze badges
While the template approach is clever for various reasons, it is important to remember the lifecycle of the lambda and the captured variables. If any form of a lambda pointer is is going to be used and the lambda is not a downward continuation, then only a copying [=] lambda should used. I.e., even then, capturing a pointer to a variable on the stack is UNSAFE if the lifetime of those captured pointers (stack unwind) is shorter than the lifetime of the lambda.
A simpler solution for capturing a lambda as a pointer is:
auto pLamdba = new std::function<...fn-sig...>([=](...fn-sig...){...});
e.g.,
new std::function<void()>([=]() -> void {...}
Just remember to later
delete pLamdba
so ensure that you don't leak the lambda memory.Secret to realize here is that lambdas can capture lambdas (ask yourself how that works) and also that in order for std::function
to work generically the lambda implementation needs to contain sufficient internal information to provide access to the size of the lambda (and captured) data (which is why the delete
should work [running destructors of captured types]).smallscriptsmallscript
As it was mentioned by the others you can substitute Lambda function instead of function pointer. I am using this method in my C++ interface to F77 ODE solver RKSUITE.
gre_gor4,42199 gold badges2929 silver badges3232 bronze badges
beniekgbeniekg
A shortcut for using a lambda with as a C function pointer is this:
Using Curl as exmample (curl debug info)
janCoffeejanCoffee
Not the answer you're looking for? Browse other questions tagged c++c++11lambdafunction-pointers or ask your own question.
In this article we will discuss how to start a thread by a member function of class.
Starting thread with non static member function
Suppose we have a class Task, which has non static member function execute() i.e.
![C++ member functions C++ member functions](/uploads/1/2/4/9/124981008/584957929.png)
2 | std::threadth(&Task::execute,taskPtr,'Sample Task'); |
Here in std::thread constructor we passed 3 arguments i.e.
1.) Pointer to member function execute of class Task
When std::thread will internally create a new thread, it will use this passed member function as thread function. But to call a member function, we need a object.
When std::thread will internally create a new thread, it will use this passed member function as thread function. But to call a member function, we need a object.
2.) Pointer to the object of class Task
As a second argument we passed a pointer to the object of class Task, with which above member function will be called. In every non static member function, first argument is always the pointer to the object of its own class. So, thread class will pass this pointer as first argument while calling the passed member function.
As a second argument we passed a pointer to the object of class Task, with which above member function will be called. In every non static member function, first argument is always the pointer to the object of its own class. So, thread class will pass this pointer as first argument while calling the passed member function.
3.) String value
This will be passed as second argument to member function i.e. after Task *
This will be passed as second argument to member function i.e. after Task *
Checkout complete example as follows,
2 4 6 8 10 12 14 16 18 20 22 24 26 28 | #include <thread> classTask public: { { } { std::threadth(&Task::execute,taskPtr,'Sample Task'); th.join(); delete taskPtr; } |
Output:
2 4 6 8 10 12 14 16 18 20 22 24 | #include <thread> classTask public: { { } { std::threadth(&Task::test,'Task'); th.join(); } |
Output
2 4 | Task::1 Task::3 |
Join LinkedIn Group of Python Professional Developers who wish to expand their network and share ideas.
You can also follow us On Twitter :