带有自定义deleter的Unique_ptr构造函数被删除

unique_ptr constructor with custom deleter is deleted

本文关键字:ptr 构造函数 删除 Unique 自定义 deleter      更新时间:2023-10-16

使用gcc 4.8.3编译并运行良好:

#include <memory>
#include <functional>
#include <iostream>
int main() {
    auto str = new const char[6]{'h', 'e', 'l', 'l', 'o', ''};
    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):错误C2280:"std:: unique_ptr>:: unique_ptr> (_Ptr2 _Dx2):试图引用已删除的函数与[_Ptr2=const char *, _Dx2=main::]C:Program Files (x86)Microsoft Visual Studio 12.0VCINCLUDEmemory(16 16):参见` std::unique_ptr>::unique_ptr'的声明

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

unique_ptr类有这样一个构造函数,用于接受指针和删除器:

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. 如果你想做其他事情,你应该使用非专业版本。