unique_ptr 具有自定义删除器的构造函数已删除

unique_ptr constructor with custom deleter is deleted

这个例子在 gcc 4.8.3 下编译和运行良好:

#include <memory>
#include <functional>
#include <iostream>

int main() {
    auto str = new const char[6]{'h', 'e', 'l', 'l', 'o', '[=11=]'};
    std::unique_ptr<const char[], std::function<void(const char *)>> u_ptr(str, [](const char *s){ delete[] s; });
    std::cout << u_ptr.get() << std::endl;
}

但是当我尝试使用 Visual Studio Professional 2013 时,它无法编译(抱怨函数被删除)。 Visual Studio 2013 还不可能做到这一点吗?还是我的示例代码有误,gcc 忽略了我的错误?

错误是:

main.cpp(8) : error C2280: 'std::unique_ptr>::unique_ptr>(_Ptr2,_Dx2)' : attempting to reference a deleted function with [ _Ptr2=const char * , _Dx2=main:: ] C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\memory(16 16) : see declaration of 'std::unique_ptr>::unique_ptr'

这似乎是 Visual C++ 2013 标准库中的一个缺陷。我无法重现 2015 年的问题。

unique_ptr class 有这个构造函数用于获取指针和删除器:

unique_ptr(pointer _Ptr,
    typename _If<is_reference<_Dx>::value, _Dx,
        const typename remove_reference<_Dx>::type&>::type _Dt) _NOEXCEPT
    : _Mybase(_Ptr, _Dt)
    {   // construct with pointer and (maybe const) deleter&
    }

然而,unique_ptr<T[]> 专业化也有一个包罗万象的构造函数:

template<class _Ptr2,
    class _Dx2>
    unique_ptr(_Ptr2, _Dx2) = delete;

此版本优于上一版本。

但是,由于非专业 unique_ptr 根本没有,将 u_ptr 更改为 const char 而不是 const char[] 可以解决问题。

像你这样使用带有删除器的数组版本也是不必要的:

  1. 如果你想在你的指针上调用 delete[],已经有数组的特化。您不需要自定义删除器。

  2. 如果你想做其他事情,你应该使用非专业版。