Почему спецификация noexcept `operator = (T & amp; t)` `std: variable` не зависит от спецификации noexcept деструктора внутренних типов?

Длинное название: почему std:variant«s operator=(T&& t)спецификация noexcept не зависит от спецификации noexcept деструктора внутренних типов?

Я могу видеть на cppreference тот

template <class T> variant& operator=(T&& t) noexcept(/* see below */);

является

noexcept(std::is_nothrow_assignable_v<T_j&, T> &&
std::is_nothrow_constructible_v<T_j, T>)

Итак, это компилируется:

struct FooThrow {
~FooThrow() noexcept(false) {throw;}
};
static_assert(std::is_nothrow_assignable_v<std::variant<FooThrow, int>, int>);

Но это вызывает FooThrowдеструктор который noexcept(false):

std::variant<FooThrow, int> x;
x = 3; // throws

Это не кажется правильным. Я что-то пропустил?

3

Решение

Как правило, стандартные типы библиотек не относятся к типам, имеющим деструкторы броска. Или, в частности, когда деструктор фактически выдает исключение. Там есть общее правило об этом ( [res.on.functions] )

В некоторых случаях (функции замены, функции-обработчики, операции над типами, используемыми для создания экземпляров стандартных шаблонных компонентов библиотеки) стандартная библиотека C ++ зависит от компонентов, предоставляемых программой C ++. Если эти компоненты не соответствуют их требованиям, этот международный стандарт не устанавливает требований к реализации.

В частности, эффекты не определены в следующих случаях:

  • если какая-либо замещающая функция или функция-обработчик или операция деструктора завершается через исключение, если это специально не разрешено в соответствующем Обязательном поведении: параграф.

поскольку variant::operator= не имеет специального утверждения о метании деструкторов, если эти деструкторы действительно выбрасывают — это UB.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]