Помогите с синтаксисом шаблона функции

Я пытаюсь понять следующий фрагмент кода из примера Espressif OTABasic для модуля беспроводной связи/BT ESP32 (см. в этом репозитории полный код).

 ArduinoOTA
.onStart([]() {
  String type;
  if (ArduinoOTA.getCommand() == U_FLASH)
    type = "sketch";
  else // U_SPIFFS
    type = "filesystem";

  // ПРИМЕЧАНИЕ: при обновлении SPIFFS это будет место для размонтирования SPIFFS с помощью SPIFFS.end()
  Serial.println("Start updating " + type);
})
.onEnd([]() {
  Serial.println("\nEnd");
})
.onProgress([](unsigned int progress, unsigned int total) {
  Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
})
.onError([](ota_error_t error) {
  Serial.printf("Error[%u]: ", error);
  if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
  else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
  else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
  else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
  else if (error == OTA_END_ERROR) Serial.println("End Failed");
});

Исходное «ArduinoOTA» выглядит как подразумеваемое выражение «with ArduinoOTA», но я не могу найти ничего подобного в справочных документах. Я знаю, что это как-то связано с шаблонами функций в «ArduinoOTA.h», но мне не под силу разобраться в синтаксисе.

Могу ли я купить подсказку, пожалуйста?

ТИА

Фрэнк

Спасибо всем за подсказки; Я старый программист C/C++, но, должно быть, проспал класс «лямбда-функции» ;-).

Чтобы помочь моему несколько обызвествленному мозгу, будет ли функционально эквивалентно (хотя и более неуклюже) написать приведенный выше фрагмент, как показано ниже, с функциями обработчика 'unchained'?

    ArduinoOTA.onStart
([]() //лямбда-функция
    { 
        String type;
        if (ArduinoOTA.getCommand() == U_FLASH)
            type = "sketch";
        else // U_SPIFFS
            type = "filesystem";

        // ПРИМЕЧАНИЕ: при обновлении SPIFFS это будет место для размонтирования SPIFFS с помощью SPIFFS.end()
        Serial.println("Start updating " + type);
    }
);

ArduinoOTA.onEnd
([]() //лямбда-функция
    {
        Serial.println("\nEnd");
    }
);

ArduinoOTA.onProgress
([](unsigned int progress, unsigned int total) // лямбда-функция с аргументами
    {
        Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    }
);

ArduinoOTA.onError
([](ota_error_t error) //лямбда-функция с аргументами
    {
        Serial.printf("Error[%u]: ", error);
        if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
        else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
        else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
        else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
        else if (error == OTA_END_ERROR) Serial.println("End Failed");
    }
);

ТИА

Фрэнк

, 👍1


1 ответ


2

Это называется (во всяком случае, мной) "цепочкой методов".

На самом деле ничего особенного. ArduinoOTA — это просто экземпляр класса ArduinoOTAClass.

Каждый метод этого класса делает то, что ему нужно, а затем возвращает ссылку на объект, внутри которого находится метод. Это означает, что вы можете затем вызвать метод для этой возвращаемой ссылки... и т.д.

Все остальное — это "лямбда"-функции, то есть функции, встроенные в параметры вызываемых функций.

Основной результат примерно такой:

A.foo().bar().baz();

Где A.foo() возвращает, AAbar() возвращает, AAbaz() возвращает A.

То же самое можно сделать с:

A.foo();
A.bar();
A.baz();
,

этот фрагмент выглядит как объявление нескольких обработчиков событий или перегрузка нескольких обработчиков событий, @jsotola

@jsotola Это просто передача анонимных («лямбда») функций в качестве параметров простым методам, которые затем сохраняют эти функции как указатели и снова возвращают объект. В этом нет ничего волшебного, никаких перегрузок или чего-то в этом роде., @Majenko

я узнаю что-то новое каждый день ... спасибо, @jsotola