1

Using the Ticker library for the ESP32, how can I use a lambda as an argument to the attach method?

tickerSystemManager.attach(1000, [&](){
 systemManager->sync();
});

Attempting to use the above, I get the following error:

Matrx.cpp:11:4: error: no matching function for call to 'Ticker::attach(int, Matrx::setup()::<lambda()>)'
...
Ticker.h:40:8: note: candidate: void Ticker::attach(float, Ticker::callback_t)

How can I capp a lambda into this method?

asked Jan 31, 2021 at 1:54
3
  • 2
    Lambda expressions that take have no captures generate some implementation type that is implicitly convertible to a basic pointer to function type. Lambda expressions that have a capture group don't qualify for that and are generally speaking not going to be compatible, because in practice what the compiler generates is a class whose members represent the captures, which makes the pointer into a pointer to class member function and therefore incompatible with regular pointer to function. Commented Jan 31, 2021 at 2:26
  • So what can I do to call the sync method of my object? It seems as if every attempt to do so give me some error or another. Commented Jan 31, 2021 at 5:37
  • If systemManager is a global, just remove the & from the capture. Commented Jan 31, 2021 at 9:30

1 Answer 1

3

As @timemage explains in a comment, you cannot pass a capturing lambda to a function that expects a plain pointer to function. There is, however, a way out of this: the Ticker class provides an overload of the attach() method that allows you to provide a parameter of any type to tour callback:

template<typename TArg>
void attach(float seconds, void (*callback)(TArg), TArg arg)

You can use this version of attach() and provide it both

  • a non-capturing lambda that gets a pointer to systemManager
  • that pointer as a third argument.

Edit: I did a few tests, and it seems my compiler cannot properly perform template argument deduction in this case, but the approach works if you explicitly specialize the template. Namely:

tickerSystemManager.attach<typeof systemManager>(
 1000,
 [](typeof systemManager p){ p->sync(); },
 systemManager);
answered Jan 31, 2021 at 12:30
3
  • You've managed to make this on topic. Might as well go a step further and show the user-data-capable overload in the context of a lambda expression. Commented Jan 31, 2021 at 13:30
  • @timemage: Good suggestion. I updated the answer. Commented Jan 31, 2021 at 16:40
  • I really appreciate the answer, this compiled and seems to run as expected! I am still trying to learn Cpp while setting up an ESP project and you are definitely giving me more to look into! Commented Feb 2, 2021 at 6:54

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.