我有一个函数定义,它以函数指针作为参数:
void ReadLogFile(void (*msgHandler)(String msg) = NULL)
{
...
if (msgHandler) msgHandler(msg);
...
}
我尝试通过 lambda 来调用它:
logger.ReadLogFile([](String s)
{
MQTT_SendLogEntry(telemetry_topic, s, s);
});
事实证明,这不起作用,因为telemetry_topic
它位于 lambda 外部,并且无法访问外部变量。因此,我更改了 lambda 以捕获所有外部变量:
logger.ReadLogFile([&](String s)
{
MQTT_SendLogEntry(telemetry_topic, s);
});
这次我收到一个编译错误:
不存在从“lambda [](String s)->void”到“void (*)(String msg)”的合适转换函数
我不知道如何改变声明logger.ReadLogFile()
来接受这样的 lambda 函数,然后如何从那里调用它。
不幸的是,如果没有捕获,lambda 只能转换为函数指针(更多信息请参见此处)。
您可以改为使用参数 a
std::function
,在这种情况下它看起来像这样:或者,如果可能的话,你可以制作
ReadLogFile
一个模板,它也允许它接受 lambda,在这种情况下它看起来像这样最简单的方法是将其制作成模板:
这也接受普通函数(
Handler
将被推导为函数指针)。如果要处理空指针,可以为函数指针添加重载(就像原始函数一样)。为了不重复代码,您可以在检查空值后委托给上述模板,但这实际上取决于您的实际代码。以下是一个例子:
关于使用
std::function
。首先,arduino 是一个独立的环境,它没有std::function
。但即使这是一个选项,由于它的类型擦除性质,std::function
(或等效)也会产生不可忽略的运行时成本(在创建和每次调用时)。