You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:43:20