次のプログラムを検討してください。
#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 のように)。