1

I want to pass a lambda function as an argument to a method. Example:

T reduce(const T initial, const std::function<T(T, T)> acc) {
    T value = initial;
    for (size_t i = 0; i < S; ++i) {
        value = acc(value, this->values[i]);
    }

    return value;
}

...

int sum = this->reduce(42, [](int acc, int value) { return acc + value; });

If I try to compile this code for Arduino, I get an obvious error:

error: 'function' in namespace 'std' does not name a template type

How can I use a lambda function in Arduino?

1 Answers1

1

std::function is not supported by the Arduino environment. (Edit: as mentioned by KIIV in a comment, it's supported on ARM targets, but not on AVR.) You can, however, pass a non-capturing lambda to a function that expects a plain function pointer. For example, given

T reduce(const T initial, T (*acc)(T, T)) {
    T value = initial;
    for (size_t i = 0; i < S; ++i) {
        value = acc(value, this->values[i]);
    }
    return value;
}

You can call it as

int sum = test.reduce(42, [](int acc, int value){ return acc + value; });

If you want your lambda to capture something, it would seem you are out of luck...

Edgar Bonet
  • 39,449
  • 4
  • 36
  • 72
  • Not completely true. It's not supported by avr-g++ compiler. However compilers for ARM based arduinos usually have full support of STL libraries including std::function – KIIV Sep 24 '20 at 19:06
  • 1
    @KIIV: thanks for the heads up. I edited the answer. – Edgar Bonet Sep 24 '20 at 19:32
  • You can emulate a closure by an instance of a helper class that stores the captured values and implements the function. I didn't try it, but I expect it to work even for AVRs. – the busybee Sep 26 '20 at 16:23