Специфікатори винятків були застарілими, оскільки специфікатори винятків, як правило, жахлива ідея . noexceptбуло додано, тому що це єдино корисне використання специфікатора винятку: знати, коли функція не кине виняток. Таким чином, він стає двійковим вибором: функції, які будуть кидати, і функції, які не будуть кидати.
noexceptбуло додано, а не просто видалення всіх специфікаторів кидання, крім того, throw()що noexceptє більш потужним. noexceptможе мати параметр, який час компіляції перетворюється на булевий. Якщо булева правда, то noexceptпалички. Якщо булева помилка, то noexceptвона не прилипає і функція може кинутись.
Таким чином, ви можете зробити щось подібне:
struct<typename T>
{
void CreateOtherClass() { T t{}; }
};
Є чи CreateOtherClassвиключення кидка? Це може бути, якщо Tконструктор за замовчуванням може. Як нам сказати? Подобається це:
struct<typename T>
{
void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; }
};
Таким чином, CreateOtherClass()буде кидати iff, якщо цей конструктор за замовчуванням кидає. Це виправляє одну з головних проблем із специфікаторами винятків: їх нездатність розповсюджувати стек викликів.
Ви не можете цього зробити throw().
noexceptможе призвести до перевірки часу виконання. Основна відмінність між ними полягає в тому, що розривnoexceptпричинstd::terminateпри порушенніthrowпричинstd::unexpected. Також дещо інша поведінка розкручується у цих випадках.