使用 std::enable_if 重载 std::unique_ptr 删除器方法

Dea*_*con 1 c++ templates sfinae unique-ptr c++20

我正在尝试为我的 编写一个删除器std::unique_ptr,并且我想重载删除方法。这是我尝试过的,但编译器抱怨使用std::enable_if_t. 代码是使用-std=c++20标志编译的。

template <class T>
class custom_deleter
{
public:
    template <class U, std::enable_if_t<std::is_array_v<T>, bool> = true>
    void operator()(U* ptr) { std::cout << "array"; }

    template <class U, std::enable_if_t<!std::is_array_v<T>, bool> = true>
    void operator()(U* ptr) { std::cout << "non-array"; }
};
Run Code Online (Sandbox Code Playgroud)

这是编译器错误:

main.cpp:17:10: error: no type named 'type' in 'struct std::enable_if<false, bool>'
   17 |     void operator()(U* ptr) { std::cout << "non-array"; }
      |          ^~~~~~~~
Run Code Online (Sandbox Code Playgroud)

我不明白这个问题。起初,我以为我缺少std::enable_if_t可用的包含或编译标志,但这不是这里的问题。任何帮助表示赞赏。

JeJ*_*eJo 5

SFINAE 需要一个要依赖的函数的模板参数。这意味着std::enable_if_t只能应用于类模板而U不能应用于类模板TT因此,您需要以某种方式在您的 s 中包含模板参数operator()(例如class U = T),或者if constexpr就像 operator()您无论如何都可以访问一样:

template <class T>
class custom_deleter
{
public:
    template <class U = T>
    void operator()(U* ptr)
    {         
        if constexpr(std::is_array_v<U>)  std::cout << "array"; 
        else if constexpr(!std::is_array_v<U>)  std::cout << "non-array";
    }
};

int main()
{
    custom_deleter<int[2]> arrDel;
    custom_deleter<std::string> strDel;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)