Passing C++ Lambda Functions

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.

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; 
2

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.

5

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like