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

Arduino C++14/C++17无std::function下存储lambda为类成员问题

错误根源

  • 错误1:C不支持普通类的非静态数据成员声明为模板,你写的template<typename Functor> Functor _lambda;属于非法语法,模板数据成员只能声明在模板类中,或者使用C14及以上的static模板数据成员,显然不符合你存储实例私有lambda的需求。
  • 错误2:模板函数的定义放在了独立的.cpp文件中,C++模板的实例化要求定义对当前编译单元可见,单独放在.cpp中的模板实现无法被其他文件调用时找到对应类型的实例,因此报未定义错误。

C++17 实现方案

你可以直接将Foo改为模板类,配合C++17的类模板参数自动推导特性,原有调用逻辑完全不需要改动,同时完全不需要引入std::function,无额外性能开销:

修改foo.h文件

// 抽象基类为可选配置,如果你需要统一持有不同lambda类型的Foo实例再加
class FooInterface {
public:
    virtual void exec(int b) = 0;
    virtual ~FooInterface() = default;
};

template<typename Functor>
class Foo : public FooInterface {
private:
    Functor _lambda;
public:
    // 构造函数直接内联实现,不需要放到cpp文件
    explicit Foo(Functor lambda): _lambda(std::move(lambda)) {}

    static auto create_lambda(int a) {
        return [a](int b) mutable {
            // 你的原有业务逻辑
            return a + b;
        };
    }

    // 实现接口方法,可选
    void exec(int b) override {
        _lambda(b);
    }
};

删除foo.cpp中的冗余代码

模板类的所有实现必须放在头文件中,删除foo.cpp中原有的构造函数定义即可。

原有调用逻辑无需修改

bar.cpp中的new Foo(Foo::create_lambda(2));可以直接编译运行,C++17会自动根据传入的lambda类型推导出Foo的模板参数。


内容的提问来源于stack exchange,提问作者scheffield

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:15:04