Ausnahmespezifizierer wurden abgelehnt, da Ausnahmespezifizierer im Allgemeinen eine schreckliche Idee sind . noexceptwurde 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.
noexceptwurde hinzugefügt, anstatt nur alle Wurfspezifizierer zu entfernen, außer throw()weil dies noexceptleistungsfähiger ist. noexceptkann einen Parameter haben, dessen Kompilierungszeit in einen Booleschen Wert aufgelöst wird. Wenn der Boolesche Wert wahr ist, bleiben die noexceptSticks. Wenn der Boolesche Wert falsch ist, noexceptbleibt der nicht hängen und die Funktion kann werfen.
So können Sie etwa Folgendes tun:
struct<typename T>
{
void CreateOtherClass() { T t{}; }
};
Wirft CreateOtherClassAusnahmen? Es könnte sein, wenn Tder 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().
noexceptkönnen Laufzeitprüfungen anfallen. Der wesentliche Unterschied zwischen ihnen , dass der Bruch istnoexceptUrsachen ,std::terminatewährend brechenthrowUrsachenstd::unexpected. Auch ein etwas anderes Abwickelverhalten des Stapels in diesen Fällen.