Передача функции в качестве аргумента с захватом, какой тип объявить в функции?
Возможно, это простое разрешение, но не удается найти правильную комбинацию.
Я пытаюсь настроить функцию (setupScreen
), чтобы она принимала в качестве аргумента функцию для фактической настройки:
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
);
});
}
Это работает, пока я не добавил [text]
для захвата переменной text
в лямбда-выражении, где это привело к следующему:
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*)){
^~~~~~~~~~~~~
Как должно выглядеть объявление моей функции, чтобы принять это?
@Snappawapa, 👍1
Обсуждение1 ответ
Лучший ответ:
ScreenHelpers::setupScreen()
ожидает, что его аргумент будет простым
функция. Захватывающая лямбда — это не простая функция: это скорее
функтор, то есть объект, который можно вызывать как функцию.
Стандартный способ передачи такой лямбда-выражения в C++ — объявить
параметр должен иметь тип std::function
:
#include <functional>
void ScreenHelpers::setupScreen(std::function<void(ThinkInk_290_Tricolor_Z10*)> setupFunc) {
...
}
Это может работать или не работать в зависимости от используемой платы Arduino.
Платы на основе AVR основаны на библиотеке C, которая лишь минимально поддерживает C++.
Вы не можете использовать <functional>
на этих платах. Если вы используете один из
этих плат, ваши варианты:
Попробуйте найти реализацию C++ STL для плат на базе AVR. Я видел по крайней мере один, плавающий в Сети.
Используйте стандартную идиому C для определения обратного вызова с
void*
параметр:
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);
Спасибо! Похоже, моя плата поддерживает лямбда-выражения, что упрощает задачу!
Второй вариант тоже пришел мне в голову, я тоже подумал, может быть, сделать параметр * data
varargs., @Snappawapa
- C++ против языка Arduino?
- Как использовать SPI на Arduino?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Ошибка: expected unqualified-id before 'if'
- Что лучше использовать: #define или const int для констант?
- Функции со строковыми параметрами
- Библиотека DHT.h не импортируется
- ошибка: ожидаемое первичное выражение перед токеном ','
Это не конкретный вопрос Arduino, это проблема чистого С++. Пожалуйста, спросите об этом на [so], если вы все еще не знаете, как это сделать, после проведения необходимых исследований., @the busybee
Я должен не согласиться, C++ Arduino — странное подмножество языка. Я бы сказал, что разумно обратиться к местам, специфичным для Arduino, для расширенных языковых функций., @Snappawapa
Компилятор, используемый Arduino, представляет собой стандартный компилятор GNU C++, предназначенный для процессоров AVR или ARM. Таким образом, он не ограничен **языком**, и мы программируем на стандартном C++. Но прилагаемые **библиотеки C++** могут быть неполными, например,
<functional>
может отсутствовать, конечно. -- Так что это помогло, если бы вы упомянули свою конкретную цель Arduino., @the busybee