Ответ 1
Эта проблема рассматривается в LWG issue 2116: std:: swap noexcept (что?), мы можем видеть это из раздела cppreference для std:: is_trivially_default_constructible:
Во многих реализациях is_nothrow_default_constructible также проверяет, выбрал ли деструктор, потому что он эффективно не отменен (T()): ошибка GCC 51452 LWG issue 2116
который обманчиво говорит только о is_nothrow_default_constructible
, но если мы подробно рассмотрим проблему, мы увидим, что она также применима и здесь.
Возможно, легче, если мы следуем отчет об ошибке gcc: [DR 2116] has_nothrow _. * ошибки конструктора, на которые ссылается первая, в которой говорится:
Признаки, которые обнаруживают конструктивность конструктора nothrow, являются ошибочными, поскольку на них влияет то, имеет ли объект nothrow dtor; разрушение вызывается в конце оценки полного выражения в noexcept (...). Все они используют шаблон построения временного внутри noexcept, тогда как они должны использовать размещение new
это явно говорит то, что на самом деле упоминается только в проблеме LWG, которая в конце концов говорит:
is_nothrow_constructible определяется в терминах is_constructible, который определяется путем просмотра гипотетической переменной и спрашивает, известно ли определение переменной, чтобы не генерировать исключения. Проблема утверждает, что это также рассматривает деструктор типа, учитывая контекст, и таким образом возвращает false, если деструктор может потенциально бросить. По крайней мере, одна реализация (Howard's) возвращает false, если конструктор не является исключением (true), а деструктор - noexcept (false). Так что не напряженная интерпретация. Проблема заключается в том, что это нужно определить с точки зрения размещения new, а не с точки зрения временного объекта, чтобы сделать его более понятным, что is_nothrow_constructible смотрит на noexcept статус только конструктора, а не деструктора.
который также влияет на std::is_trivially_default_constructible
, который полагается std:: is_trivially_constructible, который делает то же самое, что и is_constructible
, но имеет дополнительное ограничение:
но определение переменной не вызывает никакой операции, которая не является тривиальной