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
相关产品推荐
相关产品推荐

