C++20:基于输入类型特性设置函数默认参数
C++20 基于类型特性自动适配默认删除器的实现
需求
根据输入类型的特性自动调整函数默认参数:当输入类型为具备get_allocator()成员函数的PMR对象时,默认使用专属的PMR删除器;其他类型则使用常规delete逻辑。要求采用C++20特性(优先Concepts/if constexpr),避免SFINAE,尽量不编写重载函数。
初始实现(存在不足)
最初的实现无法自动识别PMR类型,默认只能绑定常规删除器:
template<typename T> void new_deleter(T* ptr) { delete ptr; } template <typename T> void pmr_deleter(T* ptr) { ptr->get_allocator().delete_object(ptr); } template<typename T> using deleter_t = void (*)(T*); // 默认使用new_deleter,无法自动适配PMR类型 template<typename T> void delete_object(T* ptr, deleter_t<T> deleter = &new_deleter<T>) { deleter(ptr); }
C++20 Concepts优化方案
通过带Concepts约束的get_default_deleter()函数,让编译器自动推导合适的默认删除器:
template<typename T> using deleter_t = void (*)(T*); template<typename T> void new_deleter(T* ptr) { delete ptr; } template <typename T> void pmr_deleter(T* ptr) { ptr->get_allocator().delete_object(ptr); } // 默认返回常规删除器 template<typename T> deleter_t<T> get_default_deleter() { return &new_deleter<T>; } // 仅当T*能调用get_allocator()时,启用该重载 template<typename T> deleter_t<T> get_default_deleter() requires requires (T* ptr) { ptr->get_allocator(); } { return &pmr_deleter<T>; } // 自动匹配对应默认删除器 template<typename T> void delete_object(T* ptr, deleter_t<T> deleter = get_default_deleter<T>()) { deleter(ptr); }
实现说明
- 利用C++20的Concepts
requires子句实现重载决议的约束,仅当类型满足PMR特性时,才会选择PMR删除器的重载版本 delete_object的默认参数会根据T的特性自动适配,无需手动指定- 完全避免了SFINAE,代码可读性和维护性更强
内容的提问来源于stack exchange,提问作者Ahmed AEK
相关产品推荐
相关产品推荐

