Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simplest way to pass a lambda as a method parameter in C++17

Tags:

c++

c++17

Google is showing me lots of SO posts on passing lambdas as arguments, but they all seem to be C++0x/C++11 based (e.g. Use a lambda as a parameter for a C++ function) and I understand this is an area that has improved in more recent C++ versions?

I want to pass what is effectively a very simple delegate return MyGlobals.GetX() as a method variable - in my case MyGlobals is a global object. i.e. in pseudocode

//stores and/or calls the lambda
myObject.SetXGetter({return MyGlobals.GetX()});

MyObject::SetXGetter(lambda?)
{
 this->mLambda = Lambda;
 cout << mLambda();
}

Older C++ versions made this quite messy having to use STL wrappers and temporary types, so in C++17 and above, how neatly can it be done... what would SetGetter look like and can it be called passing the lambda directly in?

(If there are different alternatives for even newer versions, please share)

like image 998
Mr. Boy Avatar asked Dec 31 '22 16:12

Mr. Boy


1 Answers

A function that just wants to invoke a passed lambda or other functor during its own execution can be a function template, deducing the type of the functor:

template <typename F>
void use_it(F&& func) {
    do_something_with(func());
}

Here you want to store the functor to be invoked later, so we'll need a common type that can wrap around various sorts of functors. This is what std::function is for. Assuming a return type of int:

#include <functional>

class MyObject {
// ...
private:
    std::function<int()> mLambda;
};
void MyObject::SetXGetter(std::function<int()> func) {
    mLambda = std::move(func);
}

Your call is missing the initial [captures] which is required for a lambda expression, even if nothing is captured:

myObject.SetXGetter([]{ return MyGlobals.GetX(); });
like image 167
aschepler Avatar answered Jan 11 '23 22:01

aschepler