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?

3
  • 1
    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.
    – timemage
    Jan 31 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.
    – Matt Clark
    Jan 31 at 5:37
  • If systemManager is a global, just remove the & from the capture.
    – Mat
    Jan 31 at 9:30
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);
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.
    – timemage
    Jan 31 at 13:30
  • @timemage: Good suggestion. I updated the answer. Jan 31 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!
    – Matt Clark
    Feb 2 at 6:54

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.