Ответ
noexcept — это спецификатор и оператор, введенный в C++11, который указывает, что функция не генерирует исключений. Если функция, объявленная как noexcept, все же выбросит исключение, будет вызвана функция std::terminate(), что приведет к аварийному завершению программы.
1. Синтаксис и использование:
// 1. Функция, которая не бросает исключения
void my_function() noexcept {
// ... код без throw
}
// 2. Условный noexcept. Функция noexcept, если выражение в скобках истинно.
// Например, перемещающий конструктор может быть noexcept, если перемещение
// всех членов класса не бросает исключений.
template<typename T>
void swap(T& a, T& b) noexcept(noexcept(a.swap(b))) {
a.swap(b);
}
// 3. Оператор noexcept. Возвращает true, если выражение не генерирует исключений.
bool will_throw = noexcept(throw std::runtime_error("")); // false
bool wont_throw = noexcept(1 + 2); // true
2. Ключевые причины для использования noexcept:
-
Оптимизация: Компилятор может генерировать более эффективный код, так как ему не нужно подготавливать механизм раскрутки стека для обработки исключений.
-
Гарантии безопасности исключений в STL: Многие алгоритмы и контейнеры стандартной библиотеки используют перемещающие операции (конструктор перемещения, оператор присваивания перемещением) только если они объявлены как
noexcept. В противном случае, для обеспечения строгой гарантии безопасности исключений, библиотека может откатиться к более медленному копированию.class MyType { std::vector<int> data; public: // Перемещающий конструктор с noexcept — критически важен для эффективности MyType(MyType&& other) noexcept : data(std::move(other.data)) {} // ... };При
std::vector::resize, если перемещающий конструкторnoexcept, элементы будут перемещены. Если нет — скопированы. -
Улучшение читаемости интерфейса: Явно указывает на намерение разработчика и контракт функции.
3. Важные правила:
- Деструкторы по умолчанию неявно объявлены как
noexcept. - Все функции стандартной библиотеки, которые не предназначены для генерации исключений, помечены как
noexcept. noexceptявляется частью типа функции. Указатели на функции сnoexceptи без него — разные типы.- Не стоит бездумно помечать все функции как
noexcept. Это должно быть осознанное решение, основанное на реализации функции и операций, которые она вызывает.