【问题标题】:unique_ptr constructor with custom deleter is deleted带有自定义删除器的 unique_ptr 构造函数被删除
【发布时间】:2015-08-15 04:59:03
【问题描述】:

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

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

int main() {
    auto str = new const char[6]{'h', 'e', 'l', 'l', 'o', '\0'};
    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.0\VC\INCLUDE\memory(16 16) : 参见 'std::unique_ptr>::unique_ptr' 的声明

【问题讨论】:

  • 应该有一个常见问题解答“为什么使用std::function 作为unique_ptr 删除器是一个糟糕的主意?”
  • 不应该Tchar 而不是char const[]?这适用于 Visual C++ 2015 RC。
  • std::unique_ptr already supports delete[] 没有理由在这里写你自己的。
  • @T.C.:您能否详细说明或提供一些链接说明为什么这是一个坏主意?
  • @rodrigo 例外。 unique_ptr 要求与其删除器关联的所有操作不得抛出; std::function 的构造函数可以抛出,因为它使用类型擦除并且可能需要在后台分配内存。 (在 OP 的代码中情况更糟,因为 std::function 将在调用 unique_ptr 的构造函数之前构造,如果抛出,则无论 unique_ptr 需要什么,指针都会泄漏。)

标签: c++ visual-c++ unique-ptr


【解决方案1】:

这似乎是 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&lt;T[]&gt; 特化也有一个包罗万象的构造函数:

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

这个版本比上一个更受欢迎。

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

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

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

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

【讨论】:

  • 正如我在对问题std::unique_ptr&lt;T[]&gt; 的评论中提到的,已经提供。这里不需要自定义删除器。
  • @Mgetz OP 询问他的代码在语法上是否正确(以及为什么编译器不同意)。已经合适的删除器的存在是无关紧要的,因为他提供了MCVE,在实际的实际问题中,他可能需要使用自定义删除器。
猜你喜欢
  • 1970-01-01
  • 2020-02-25
  • 1970-01-01
  • 1970-01-01
  • 2013-03-30
  • 2016-11-23
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
相关资源
最近更新 更多