C++静态成员函数与lambda作为unique_ptr删除器的优劣及开销对比
Lambda删除器版本优缺点及性能对比
注:你提供的两段示例代码都存在几处语法笔误,比如
derived_handle别名定义缺少右尖括号、CRTP基类实例化未传Derived模板参数、构造unique_ptr时参数括号不匹配,调整之后逻辑才能正常运行。
Lambda版本的优缺点
优点
- 代码内聚性更高:删除逻辑直接定义在使用位置,不需要额外维护类的私有模板成员函数,阅读代码时不需要跳转查找删除器实现
- 不容易出现模板参数匹配错误:你写的静态成员版本实际存在模板参数不匹配的问题(
_deleter的模板参数未对应到实际派生类的CRTP基类类型,static_cast转换时也没有指定Base的模板参数),lambda直接绑定当前上下文的Derived类型,能避免这类写法错误 - 不会污染类的命名空间:不需要为类新增额外的私有成员,也不会出现命名冲突的问题
缺点
- 依赖更高的C标准:你用的
auto参数泛型lambda是C14才支持的特性,如果项目需要兼容C++11,需要手动给lambda写模板参数,写法反而不如静态成员函数简洁 - 复用性差:lambda是函数内部的局部定义,如果后续其他地方也需要用到相同的删除逻辑,没法直接复用,需要单独抽离定义
- 调试难度稍高:编译器生成的lambda符号名是自动生成的乱序字符串,排查崩溃看调用栈时,不如静态成员函数的符号名直观好定位
- 存在隐式约束陷阱:你当前用的无捕获lambda才能隐式转换为普通函数指针,匹配你
derived_handle的删除器类型,如果后续修改lambda时加了捕获(比如要传入上下文打日志、统计销毁次数),会直接编译失败,而且报错信息通常不直观,新手很难快速定位问题
运行开销差异
二者的运行开销完全一致,没有任何区别:
无捕获lambda转换为函数指针后,本质上和静态成员函数的底层实现完全相同,都是存储在代码段的函数地址。你的derived_handle是固定的std::unique_ptr<void, void(*)(void*)>类型,两种实现的内存布局都是1个指针+1个函数指针,调用删除器的路径也完全相同,开启编译器优化后生成的汇编代码没有任何差异,不存在性能高低的区别。
内容的提问来源于stack exchange,提问作者Symlink
相关产品推荐
相关产品推荐

