Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing C++ Lambda Functions

Tags:

c++

lambda

I've been searching everywhere for this, and I don't seem to be able to find a straight answer. Some sources say this isn't possible, but that only raises more questions for me, which I'll explain further below.

So here's the situation. Suppose I have a custom container class with a selection function like below (this is just an example):

template <typename T> class Container { public:     // ...      Container<T> select(bool (*condition)(const T&)) const;      // ... }; 

So as you can see, the select function takes a pointer to a condition function. This is a function that defines which items should be selected. So, an example use of this would be something similar to:

bool zero_selector(const int& element) {     return (element == 0); // Selects all elements that are zero } 

Now if I have a container filled with, say s = { 1, 1, 0, 0, 1, 0, 1, 0 }, I could select a subset of these that would only contain zeroes using:

t = s.select(&zero_selector); // t = { 0, 0, 0, 0 } 

As you can see, this is a bit clunky. Lambda functions would make this much more elegant, so then I could use (I'm not sure if this is the correct syntax for it), for example:

t = s.select([&] (int x) -> bool { return (x == 0); }); 

My question is, is this possible? If so, what should my function prototype be for Container::select() to accept a lambda as one of its parameters?

If it isn't possible, then how is something like std::for_each implemented that can use a lambda expression as one of its arguments? Any resources that would clearly explain this would be much appreciated. Everything I've found just gives examples of lambda functions and using std::function<> to pass them as parameters, but nothing explains how std::for_each works with lambda functions.

I'd like to note that this code isn't compiled/tested as-is. It's for demonstration purposes only. I have tried implementing the same principles in the actual project and it doesn't work.

like image 495
Zeenobit Avatar asked Sep 27 '11 18:09

Zeenobit


People also ask

Does C support lambda function?

the C standard does not define lambdas at all but the implementations can add extensions. Gcc also added an extension in order for the programming languages that support lambdas with static scope to be able to convert them easily toward C and compile closures directly.

Can you pass lambda to function C++?

One of the new features introduced in Modern C++ starting from C++11 is Lambda Expression. It is a convenient way to define an anonymous function object or functor. It is convenient because we can define it locally where we want to call it or pass it to a function as an argument.

What is lambda function in C++11?

In C++11 and later, a lambda expression—often called a lambda—is a convenient way of defining an anonymous function object (a closure) right at the location where it's invoked or passed as an argument to a function.


2 Answers

There's no need to add the knee-jerk [&]-capture. Your lambda doesn't need it:

[] (int x) -> bool { return (x == 0); } 

Captureless lambdas are convertible to the corresponding function pointer, so this should work out of the box.

That said, you should probably declare the select function to accept std::function, to which all lambdas are convertible, capturing or not:

Container<T> select(std::function<bool(const T&)> predicate) const; 
like image 181
Kerrek SB Avatar answered Oct 15 '22 00:10

Kerrek SB


You need to declare your lambda as stateless (that is, with an empty capture specification [](int x)-> bool {...}) for it to be convertable to a function pointer.

like image 29
MSN Avatar answered Oct 15 '22 01:10

MSN