C++ function
简单记录下编写代码时遇到的问题:
在调用一个接口的时候,需要传入一个std::function类型的参数。
之前在调用此接口时传入的参数lambda表达式类型。由于接口的定义为function<void()>类型,而在调用传入参数时,需要遍历数组,处理数组中的成员。若采用lambda的方式,只能通过捕获的方式传值,考虑到作用域和lambda之间的干扰,应采用值捕获的方式。代码看起来像这样:
void deal(const function<void()>& func) { func(); } int main(int argc, char* argv[]) { vector<int> nums = { 1,2,3,4 }; for (auto num:nums) { auto func = [num]() { cout << num << endl; }; deal(func); } return 0; }
实际的处理func处理过程很复杂,将lambda表达式在for循环中定义,代码段过长。而且此函数是多次定时调用,涉及到内存分配, 采用lambda需要每次重新分配内存,每次使用完之后释放,效率较低。
改为使用仿函数,则代码如下:
class A { public: A(int num):_num(num) {} void operator()() { std::cout << _num << std::endl; } private: int _num; }; void deal(const function<void()>& func) { func(); } int main(int argc, char* argv[]) { vector<int> nums = { 1,2,3,4,5,6 }; for (auto num:nums) { A a(num); deal(a); } return 0; }
需要注意的是:
在构造function时,会对仿函数进行拷贝构造和移动构造,在VS2019中的实现如下:
template <class _Fx, typename _Mybase::template _Enable_if_callable_t<_Fx&, function> = 0> #else // ^^^ _USE_FUNCTION_INT_0_SFINAE // !_USE_FUNCTION_INT_0_SFINAE vvv template <class _Fx, class = typename _Mybase::template _Enable_if_callable_t<_Fx&, function>> #endif // _USE_FUNCTION_INT_0_SFINAE function(_Fx _Func) { this->_Reset(_STD move(_Func)); }
即:在构造function时,先按值传递仿函数对象,调用一次拷贝构造函数,在function函数内部再调用移动构造函数。实现仿函数时,若涉及到内存申请释放,应自定义拷贝构造函数和移动构造函数,避免浅拷贝引起的问题。
编译器默认生成的拷贝构造函数和移动构造函数相关问题参见:
https://www.cnblogs.com/yajiu/articles/15435277.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 为DeepSeek添加本地知识库
· .NET程序员AI开发基座:Microsoft.Extensions.AI
· 精选4款基于.NET开源、功能强大的通讯调试工具
· 数据不出内网:基于Ollama+OneAPI构建企业专属DeepSeek智能中台
· 大模型工具KTransformer的安装