Рассмотрим следующую программу:
#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 является... destructor... он подразумевает спецификацию исключительных спецификаций... f имеет спецификацию исключения
noexcept(true)
, если каждая функция, которую он вызывает непосредственно, не позволяет исключений.
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
в этом примере).