Рассмотрим следующую программу:
#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 имеет спецификацию исключений
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
есть в примере).
TL; DR: Почему g ++ — 4.8.1 считает, что явно объявленный деструктор без спецификации исключений всегда
noexcept(true)
?
Потому что это ошибка?
Ваша интерпретация стандарта верна, и Clang правильно ее реализует (утверждение не срабатывает).
f
имеет спецификацию исключенияnoexcept(true)
если каждая функция, которую он непосредственно вызывает не допускает никаких исключений.
Деструктор напрямую вызывает деструктор всех подобъектов:
§12.4 [class.dtor] p8
:
После выполнения тела деструктора и уничтожения любых автоматических объектов, размещенных в теле, деструктор для класса
X
вызывает деструкторы для прямых не вариантных нестатических элементов данных X, […].
Других решений пока нет …