c++lambdaarduinofunction-pointersarduino-c++

Arduino C++ : how to define lambda function parameter?


I have a function definition that takes a function pointer as an argument:

void ReadLogFile(void (*msgHandler)(String msg) = NULL)
{
  ...
  if (msgHandler) msgHandler(msg);
  ...
}

I try to call this passing a lambda:

logger.ReadLogFile([](String s) 
  {
    MQTT_SendLogEntry(telemetry_topic, s, s);
  });

Turns out that this does not work because telemetry_topic is external to the lambda and it has no access to an external variable. Therefore I change the lambda to capture all external variables:

logger.ReadLogFile([&](String s) 
  {
    MQTT_SendLogEntry(telemetry_topic, s);
  });

This time I get a compilation error:

no suitable conversion function from "lambda [](String s)->void" to "void (*)(String msg)" exists

I can't figure out how to change the declaration of logger.ReadLogFile() to accept such a lambda function, and then how to invoke it from there.


Solution

  • A lambda can only be converted to a function pointer if it does not capture, unfortunately (for more, see here.

    You can make the parameter a std::function instead, in which case it'd look like this:

    void ReadLogFile(std::function<void(String)> msgHandler = nullptr)
    {
      ...
      if (msgHandler) msgHandler(msg);
      ...
    }
    

    Or, if it's possible, you can make ReadLogFile a template, which also allow it to accept a lambda, in which case it'd look like this

    template <typename Func>
    void ReadLogFile(Func msgHandler)
    {
      ...
      if (msgHandler) msgHandler(msg);
      ...
    }