16

次のプログラムを検討してください。

#include <type_traits>

struct Thrower
{
    ~Thrower() noexcept(false) { throw 1; }
};

struct Implicit
{
    Thrower t;
};
static_assert(!std::is_nothrow_destructible<Implicit>::value, "Implicit");

struct Explicit
{
    ~Explicit() {}

    Thrower t;
};
static_assert(!std::is_nothrow_destructible<Explicit>::value, "Explicit");

ではg++-4.8.1、静的アサーション障害がある、Explicitと思われるよう~Explicit()ですnoexcept。これは私の期待と一致しません。§12.4.3 によると:

例外仕様を持たないデストラクタの宣言は、暗黙の宣言と同じ例外仕様を持つと暗黙的に見なされます。

ここで面白いのは、 のチェックがImplicit、§15.4.14 (§12.4.7 まで) の私の解釈に従って動作しているように見えることです。

... fが ... デストラクタの場合 ... 暗黙の例外仕様が指定する ... f がnoexcept(true)直接呼び出すすべての関数が例外を許可しない場合、 f は例外仕様を持ちます。

g++-4.7が欠けis_nothrow_destructableているため、4.7 での動作を確認するために独自に作成しました。プログラムは完全に正常にコンパイルされているようです。私はこれが完全に間違っており、私の混乱の原因となる権利を留保します:

template <typename T>
struct is_nothrow_destructible
{
    static constexpr bool value = noexcept(std::declval<T>().~T());
};

TL;DR:g++-4.8.1例外指定のない明示的に宣言されたデストラクタが常に であると考えるのはなぜnoexcept(true)ですか?


更新:これについてバグを開きました: 57645。この問題を回避する必要がある場合は、デストラクタに例外指定を追加できます (Thrower例の has のように)。

4

1 に答える 1