Capturing lambda function as parameter

Hello,

I want to pass a lambda function as a parameter to another function.
It does not work with a member function

Error Message:
no matching function for call to 'Max6675Sensor::setInterval(const char [7], int, Max6675Sensor::setup()::<lambda()>)

The goal is to call Max6675Sensor::update() every 2000ms.

I can't use std::function -> "std::function' has not been declared"

thanks for your help!

class Max6675Sensor : public Component
void Max6675Sensor::setup()
{
    thermocouple.begin(this->clkPin, this->csPin, this->soPin);

    // does not work
    // no matching function for call to 'Max6675Sensor::setInterval(const char [7], int, Max6675Sensor::setup()::<lambda()>)'
    this->setInterval("update", 2000, [this]() {
        this->update();
    });

    // works
    this->setInterval("update", 2000, []() {
        Serial.println("Test");
    });
}

void Max6675Sensor::update()
{
    this->value = this->thermocouple.readCelsius();
    Logger->debug("sensor.max6675", "Neuer Wert: %f", this->value);
}
// Header
void setInterval(const std::string &name, uint32_t interval, void (*f)());
//
void Component::setInterval(const std::string &name, uint32_t interval, void (*f)())
{
    int offset = 0;
    if (interval != 0)
    {
        offset = (random(65535) % interval) / 2;
    }
    this->cancelInterval(name);
    struct TimeFunction function { name, TimeFunction::INTERVAL, interval, millis() - interval - offset, f, false };
    this->timeFunctions.push_back(function);
}

You cannot do that, the lambda is not part of a class, thus "this->" is not valid. You either need to specify the argument of "setInterval" as "void (Max6675Sensor::*f)()" or preferrable do an interface style declaration:

class Callable {
public:
  virtual void TheCallable() = 0;
}

class Max6675Sensor : public Callable, ... {
  void TheCallable() { .. }
}

void Component::setInterval(const std::string &name, uint32_t interval, Callable *c)
{
    int offset = 0;
    if (interval != 0)
    {
        offset = (random(65535) % interval) / 2;
    }
    this->cancelInterval(name);
    struct TimeFunction function { name, TimeFunction::INTERVAL, interval, millis() - interval - offset, c, false };
    this->timeFunctions.push_back(function);
}

and then invoke "c->TheCallable()" when the timer clicks.

Thanks for the answer.

i am not sure if the interface ist the right solution for me. I want to be able to (theoretically) add all functions to the setTimeout function.

i have read much about std:function. Do you know a library for it?
I have this one GitHub - maniacbug/StandardCplusplus: Standard C++ for Arduino (port of uClibc++) and it is not working.

The method argument must be a member of "Max6675Sensor" in order to access other members using "this->". A lambda will never be a member of a class, so you are trying to do something that is not possible AFAICT.

I implemented the Interface solution
every component has two new functions

virtual void handleInterval();
virtual void handleTimeout();

the component is passed to the timefunction.

void Component::setInterval(const std::string &name, uint32_t interval, Component *c)
{
    int offset = 0;
    if (interval != 0)
    {
        offset = (random(65535) % interval) / 2;
    }
    this->cancelInterval(name);
    struct TimeFunction function { name, TimeFunction::INTERVAL, interval, millis() - interval - offset, c, false };
    this->timeFunctions.push_back(function);
}
void Component::loopInternal()
{
    for (unsigned int i = 0; i < this->timeFunctions.size(); i++)
    {
        const uint32_t now = millis();
        TimeFunction *tf = &this->timeFunctions[i];
        if (tf->shouldRun(now))
        {
            if (tf->type == TimeFunction::INTERVAL)
            {
                tf->c->handleInterval();
            }
            else if (tf->type == TimeFunction::TIMEOUT)
            {
                tf->c->handleTimeout();
            }
        }
    }

}