Ausnahmespezifizierer wurden abgelehnt, da Ausnahmespezifizierer im Allgemeinen eine schreckliche Idee sind . noexcept
wurde hinzugefügt, weil es die einigermaßen nützliche Verwendung eines Ausnahmespezifikators ist: zu wissen, wann eine Funktion keine Ausnahme auslöst. Somit wird es eine binäre Wahl: Funktionen, die werfen und Funktionen, die nicht werfen.
noexcept
wurde hinzugefügt, anstatt nur alle Wurfspezifizierer zu entfernen, außer throw()
weil dies noexcept
leistungsfähiger ist. noexcept
kann einen Parameter haben, dessen Kompilierungszeit in einen Booleschen Wert aufgelöst wird. Wenn der Boolesche Wert wahr ist, bleiben die noexcept
Sticks. Wenn der Boolesche Wert falsch ist, noexcept
bleibt der nicht hängen und die Funktion kann werfen.
So können Sie etwa Folgendes tun:
struct<typename T>
{
void CreateOtherClass() { T t{}; }
};
Wirft CreateOtherClass
Ausnahmen? Es könnte sein, wenn T
der Standardkonstruktor dies kann. Wie erzählen wir? So was:
struct<typename T>
{
void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; }
};
Daher CreateOtherClass()
wird iff den Standardkonstruktor des angegebenen Typs auslösen. Dies behebt eines der Hauptprobleme bei Ausnahmespezifizierern: ihre Unfähigkeit, den Aufrufstapel weiterzugeben.
Das kann man nicht machen throw()
.
noexcept
können Laufzeitprüfungen anfallen. Der wesentliche Unterschied zwischen ihnen , dass der Bruch istnoexcept
Ursachen ,std::terminate
während brechenthrow
Ursachenstd::unexpected
. Auch ein etwas anderes Abwickelverhalten des Stapels in diesen Fällen.