Как использовать noexcept в операторе присваивания с идиомой копирования и замены?
оператор присваивания перемещения часто должен объявляться noexcept (т. е. для хранения типа в контейнерах STL). Но идиома копирования и подкачки позволяет определять операторы копирования и перемещения в одном фрагменте кода. Что делать с спецификатором noexcept в этом случае? Конструкция копирования может бросить, но я сомневаюсь, что она может нарушить спецификатор noexcept.
// Is it correct considering that T copy constructor can throw?
T& operator=(T other) noexcept;
2 ответов
С копия на звонящего!--5--> боковая вызова, это не является частью того, что делает ваша функция. Поэтому он не может управляться вашей функцией и, следовательно, вы не можете включить эту информацию в noexcept
спецификация.
единственное, что вы можете сделать, это, чтобы перестраховаться и добавить и вариантов noexcept
спецификация. Конечно, это означает, что вы получаете некоторые ложные негативы.
как обычно Даниель Фрей и правильно. Все, что я хочу, это показать фрагмент кода, который иллюстрирует суть.
#include <iostream>
struct foo {
foo() = default;
foo(const foo&) {
std::cout << "throw\n";
throw 1;
}
foo& operator =(foo) noexcept {
return *this;
}
};
int main() {
foo f, g;
try {
f = g; // throws
}
catch(int) {
std::cout << "catch\n";
}
}
при компиляции с gcc 4.8.1 (-std=c++11 -Wall -Wextra -pedantic
) это не дает никаких предупреждений. Запуск кода приводит к следующему выводу:
throw
catch
поэтому конструктор копирования бросает при вызове, но это не рассматривается внутри operator =()
и, следовательно,noexcept
обещание было выполнено. В противном случае, terminate будет вызван до catch
может быть распечатана.