user38608: This probably has a simple resolution, but can't find the right combination.
I'm trying to setup a function (setupScreen) to take as an argument a function to do the actual setup:
void ScreenHelpers::setupScreen(void (*setupFunc)(ThinkInk_290_Tricolor_Z10*)){
    ScreenHelpers::waitTilCanRefreshScreen();

    (* setupFunc)(&display_two);

    lastUpdateTime = millis();
}
//...
void ScreenHelpers::displayErrorMessage(const String message){
    const char* text = message.c_str();
    ScreenHelpers::setupScreen([text](ThinkInk_290_Tricolor_Z10* screen) {
        screen->clearBuffer();
        ScreenHelpers::simpleDisplayText(
            screen,
            text,
            EPD_RED
        );
     });
}

This works, until I added the [text] to capture the text variable in the lambda, where it resulted in:
ScreenHelpers.cpp: In static member function 'static void ScreenHelpers::displayErrorMessage(String)':
ScreenHelpers.cpp:45:4: error: no matching function for call to 'ScreenHelpers::setupScreen(ScreenHelpers::displayErrorMessage(String)::<lambda(ThinkInk_290_Tricolor_Z10*)>)'
   });
    ^
ScreenHelpers.cpp:21:6: note: candidate: 'static void ScreenHelpers::setupScreen(void (*)(ThinkInk_290_Tricolor_Z10*))'
 void ScreenHelpers::setupScreen(void (*setupFunc)(ThinkInk_290_Tricolor_Z10*)){
      ^~~~~~~~~~~~~

What should my function declaration look like to accept this?

user7508: ScreenHelpers::setupScreen() expects its argument to be a plain
function. A capturing lambda is not a plain function: it is rather a
functor, i.e. an object that is callable like a function.
The standard way of passing such a lambda in C++ is to declare the
parameter to be of type std::function:
#include <functional>

void ScreenHelpers::setupScreen(std::function<void(ThinkInk_290_Tricolor_Z10*)> setupFunc) {
    ...
}

This may or may not work depending on the Arduino board you are using.
AVR-based boards rely on a C library that only minimally supports C++.
You cannot use <functional> on those boards. If you are using one of
those boards, your options are:

Try to find an implementation of of the C++ STL for AVR-based boards.
I have seen at least one floating around in the Net.

Use the standard C idiom for defining a callback with a void*
parameter:


void ScreenHelpers::setupScreen(
      void (*setupFunc)(ThinkInk_290_Tricolor_Z10*, void*),
      void *callback_data) {
   setupFunc(&display_two, callback_data);
   //...
}

// elsewhere:
ScreenHelpers::setupScreen([](ThinkInk_290_Tricolor_Z10 *screen, void *data) {
   const char *text = (const char *) data;
   // ...
}, (void *) text);


38608: <p>This probably has a simple resolution, but can't find the right combination.</p>
<p>I'm trying to setup a function (<code>setupScreen</code>) to take as an argument a function to do the actual setup:</p>
<pre class="lang-cpp prettyprint-override"><code>void ScreenHelpers::setupScreen(void (*setupFunc)(ThinkInk_290_Tricolor_Z10*)){
    ScreenHelpers::waitTilCanRefreshScreen();

    (* setupFunc)(&amp;display_two);

    lastUpdateTime = millis();
}
//...
void ScreenHelpers::displayErrorMessage(const String message){
    const char* text = message.c_str();
    ScreenHelpers::setupScreen([text](ThinkInk_290_Tricolor_Z10* screen) {
        screen-&gt;clearBuffer();
        ScreenHelpers::simpleDisplayText(
            screen,
            text,
            EPD_RED
        );
     });
}
</code></pre>
<p>This works, until I added the <code>[text]</code> to capture the <code>text</code> variable in the lambda, where it resulted in:</p>
<pre><code>ScreenHelpers.cpp: In static member function 'static void ScreenHelpers::displayErrorMessage(String)':
ScreenHelpers.cpp:45:4: error: no matching function for call to 'ScreenHelpers::setupScreen(ScreenHelpers::displayErrorMessage(String)::&lt;lambda(ThinkInk_290_Tricolor_Z10*)&gt;)'
   });
    ^
ScreenHelpers.cpp:21:6: note: candidate: 'static void ScreenHelpers::setupScreen(void (*)(ThinkInk_290_Tricolor_Z10*))'
 void ScreenHelpers::setupScreen(void (*setupFunc)(ThinkInk_290_Tricolor_Z10*)){
      ^~~~~~~~~~~~~
</code></pre>
<p>What should my function declaration look like to accept this?</p>
 7508: <p><code>ScreenHelpers::setupScreen()</code> expects its argument to be a plain
function. A capturing lambda is not a plain function: it is rather a
functor, i.e. an object that is callable like a function.</p>
<p>The standard way of passing such a lambda in C++ is to declare the
parameter to be of type <a href="https://en.cppreference.com/w/cpp/utility/functional/function" rel="nofollow noreferrer"><code>std::function</code></a>:</p>
<pre class="lang-cpp prettyprint-override"><code>#include &lt;functional&gt;

void ScreenHelpers::setupScreen(std::function&lt;void(ThinkInk_290_Tricolor_Z10*)&gt; setupFunc) {
    ...
}
</code></pre>
<p>This may or may not work depending on the Arduino board you are using.
AVR-based boards rely on a C library that only minimally supports C++.
You cannot use <code>&lt;functional&gt;</code> on those boards. If you are using one of
those boards, your options are:</p>
<ol>
<li><p>Try to find an implementation of of the C++ STL for AVR-based boards.
I have seen at least one floating around in the Net.</p>
</li>
<li><p>Use the standard C idiom for defining a callback with a <code>void*</code>
parameter:</p>
</li>
</ol>
<pre class="lang-cpp prettyprint-override"><code>void ScreenHelpers::setupScreen(
      void (*setupFunc)(ThinkInk_290_Tricolor_Z10*, void*),
      void *callback_data) {
   setupFunc(&amp;display_two, callback_data);
   //...
}

// elsewhere:
ScreenHelpers::setupScreen([](ThinkInk_290_Tricolor_Z10 *screen, void *data) {
   const char *text = (const char *) data;
   // ...
}, (void *) text);
</code></pre>
