【问题标题】:unique_ptr<T,Deleter> constructor requires that Deleter is nothrowunique_ptr<T,Deleter> 构造函数要求 Deleter 不抛出
【发布时间】:2020-08-19 12:46:17
【问题描述】:

unique_ptr (constructor) @ cppreference

unique_ptr( pointer p, /* see below */ d1 ) noexcept;
(3) 
unique_ptr( pointer p, /* see below */ d2 ) noexcept;
(4)

这里有2个构造函数,对Deleter case的描述是非引用的

a) If D is non-reference type A, then the signatures are:
unique_ptr(pointer p, const A& d) noexcept;
(1) (requires that Deleter is nothrow-CopyConstructible)
unique_ptr(pointer p, A&& d) noexcept;
(2) (requires that Deleter is nothrow-MoveConstructible)

我检查了 gcc 和 llvm 代码,但我没有看到 nothrow 要求被强制执行。构造函数 3-4 标记为 noexcept,因此在调用其构造函数时不应抛出 Deleter 是有道理的。但我不确定为什么在示例中他们提供的构造函数没有标记为noexcept

struct D { // deleter
    D() {};
    D(const D&) { std::cout << "D copy ctor\n"; }
    D(D&) { std::cout << "D non-const copy ctor\n";}
    D(D&&) { std::cout << "D move ctor \n"; }
    void operator()(Foo* p) const {
        std::cout << "D is deleting a Foo\n";
        delete p;
    };
};

【问题讨论】:

    标签: c++ c++17 language-lawyer noexcept


    【解决方案1】:

    我检查了 gcc 和 llvm 代码,但我没有看到 nothrow 要求被强制执行。

    这不是直接强制执行的。
    这是actual words from the standard

    对于第一个构造函数,如果D 不是引用类型,则D 应满足Cpp17CopyConstructible 的要求,并且此类构造不应通过异常退出。对于第二个构造函数,如果D不是引用类型,D应该满足Cpp17MoveConstructible的要求,这样的构造不会通过异常退出。

    这就是说,如果您的复制/移动构造函数通过异常退出,您将有未定义的行为。 [ 在这种情况下,“应该”是对用户的要求。 ]

    如果你幸运的话,程序会调用terminate 并发送一条好消息。但是,您没有任何保证。

    (稍后)注意:要求不是它们是noexcept,而是它们不会通过异常退出。这就是 cppreference 上的示例很好的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      • 2021-08-28
      • 1970-01-01
      相关资源
      最近更新 更多