Arduino C++:如何让函数接受带捕获的Lambda作为参数?
问题描述
我定义了一个接受函数指针作为参数的函数:
void ReadLogFile(void (*msgHandler)(String msg) = NULL) { ... if (msgHandler) msgHandler(msg); ... }
尝试传递Lambda调用该函数时:
logger.ReadLogFile([](String s) { MQTT_SendLogEntry(telemetry_topic, s, s); });
发现由于Lambda无法访问外部变量telemetry_topic而无法正常工作,于是改为捕获所有外部变量:
logger.ReadLogFile([&](String s) { MQTT_SendLogEntry(telemetry_topic, s); });
此时出现编译错误:
no suitable conversion function from "lambda [](String s)->void" to "void (*)(String msg)" exists
我不清楚如何修改logger.ReadLogFile()的声明以接受这类Lambda函数,以及如何在函数内调用它。
解决方案
方法1:使用模板函数兼容任意可调用对象
这是最灵活的实现方式,能适配捕获变量的Lambda、普通函数指针、函数对象等所有可调用类型:
template<typename Handler> void ReadLogFile(Handler msgHandler = nullptr) { ... if (msgHandler) msgHandler(msg); ... }
修改后无需调整调用代码,直接传递捕获变量的Lambda即可正常编译运行。
方法2:用std::function包装可调用对象
如果不想使用模板,可借助std::function来统一处理可调用类型,需要先包含<functional>头文件:
#include <functional> void ReadLogFile(std::function<void(String)> msgHandler = nullptr) { ... if (msgHandler) msgHandler(msg); ... }
调用方式保持不变,捕获变量的Lambda会自动转换为std::function实例。
错误原因说明
只有无捕获的Lambda能隐式转换为函数指针,一旦Lambda通过[&]或[=]捕获了外部变量,它就变成了一个带有内部状态的匿名函数对象,不再符合普通函数指针的类型要求,因此会触发编译错误。
内容的提问来源于stack exchange,提问作者László Frank
相关产品推荐
相关产品推荐

