【问题标题】:Why std::unique_ptr does not explicitly require a noexcept Deleter?为什么 std::unique_ptr 没有明确要求 noexcept Deleter?
【发布时间】:2018-03-06 21:43:56
【问题描述】:

文档说 Deleter 应该是:

  • nothrow 可构造
  • nothrow 可调用(因为它是从 ~unique_ptr() noexcept 调用的
  • nothrow 可破坏(出于上述原因)

我的问题是为什么 uniqut_ptr 被定义为允许 Deleter 可能抛出。例如。所有unique_ptr 构造函数都允许以下Deleter

struct BadDeleter
{
    BadDeleter() noexcept(false) {}
    ~BadDeleter() noexcept(false) {}
    BadDeleter(const BadDeleter&) noexcept(false) {}
    BadDeleter(BadDeleter&) noexcept(false) {}
    BadDeleter(BadDeleter&&) noexcept(false) {}
    void operator()(char* p) const noexcept(false) {
        delete p;
    };
};

Live Demo

【问题讨论】:

  • 它到底在哪里说明了您在第一句话中所声称的内容?
  • 什么文件说明了这一点?
  • 构造函数是noexcept,重置是noexcept,析构函数是defined,没有noexcept(false)。我不明白在这些定义下 Deleter 可以抛出什么。
  • 如果它抛出,那么它是 UB。 noexcept 不是函数签名的一部分,因此您无法检查删除器是否被标记。
  • 啊,C++17。我忘了他们加了。他们可能会在未来的标准中更改unique_ptr。虽然你不知道它是什么时候制作的。

标签: c++ unique-ptr noexcept exception-safety


【解决方案1】:

该标准仅根据unique_ptr 的操作定义了对uniqe_ptr 删除器的要求。虽然这些要求总是说诸如

~unique_ptr();
要求:表达式 get_deleter()(get()) 格式正确,行为明确,不抛出异常。

标准从不明确规定删除器必须有一个noexceptoperator()

我认为选择此措辞是为了保持向后兼容 C++14。在该标准中,noexcept 不是函数签名的一部分,在 C++17 中添加该要求可能会破坏大量使用自定义删除器但未将其操作明确标记为 noexcept 的代码。

【讨论】:

  • 我希望在发布时编译器至少会警告缺少noexcept
猜你喜欢
  • 2016-04-10
  • 2021-01-02
  • 2020-08-19
  • 2016-05-28
  • 2019-02-10
  • 1970-01-01
  • 2017-10-18
  • 2018-07-11
  • 2021-10-16
相关资源
最近更新 更多