使用std::enable_if重载std::unique_ptr删除器方法编译报错如何解决
错误原因
std::enable_if_t 要触发SFINAE(替换失败非错误)机制,其判断条件必须依赖当前正在实例化的模板的参数。你代码里的std::is_array_v<T>用到的T是custom_deleter类的模板参数,不属于operator()成员模板自身的参数:当类被实例化时,两个operator()的enable_if条件就已经确定了一真一假,假的那个会直接触发编译错误,不会走SFINAE逻辑。
解决方案
方案1:调整模板参数让条件依赖成员模板
给operator()新增一个默认的模板参数,把判断条件绑定到这个成员模板自身的参数上,即可触发SFINAE:
template <class T> class custom_deleter { public: // 新增默认模板参数D,让is_array_v判断依赖成员模板参数 template <class U, class D = T, std::enable_if_t<std::is_array_v<D>, bool> = true> void operator()(U* ptr) { std::cout << "array"; } template <class U, class D = T, std::enable_if_t<!std::is_array_v<D>, bool> = true> void operator()(U* ptr) { std::cout << "non-array"; } };
方案2:用C++17 if constexpr简化实现
你已经使用C++20编译,完全支持if constexpr特性,不需要重载两个operator(),直接在同一个函数内做分支判断即可,代码更简洁:
template <class T> class custom_deleter { public: template <class U> void operator()(U* ptr) { if constexpr (std::is_array_v<T>) { std::cout << "array"; delete[] ptr; } else { std::cout << "non-array"; delete ptr; } } };
内容的提问来源于stack exchange,提问作者Erunehtar
相关产品推荐
相关产品推荐

