Gibt es einen Unterschied zwischen throw()
und noexcept
außer der Überprüfung zur Laufzeit bzw. zur Kompilierungszeit?
Dieser Wikipedia C ++ 11-Artikel schlägt vor, dass die C ++ 03-Wurfspezifizierer veraltet sind.
Warum ist es in der noexcept
Lage, all das zur Kompilierungszeit abzudecken?
[Hinweis: Ich habe diese Frage und diesen Artikel überprüft , konnte jedoch den soliden Grund für die Ablehnung nicht ermitteln.]
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.Antworten:
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ßerthrow()
weil diesnoexcept
leistungsfähiger ist.noexcept
kann einen Parameter haben, dessen Kompilierungszeit in einen Booleschen Wert aufgelöst wird. Wenn der Boolesche Wert wahr ist, bleiben dienoexcept
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:
Wirft
CreateOtherClass
Ausnahmen? Es könnte sein, wennT
der Standardkonstruktor dies kann. Wie erzählen wir? So was: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()
.quelle
noexcept
. Ich habe niemals einenthrow()
Spezifizierer verwendet und versuche festzustellen, obnoexcept
tatsächlich ein Nutzen erzielt wird (außer der vom Compiler geprüften Dokumentation).std::terminate
. Das ist viel schlimmer ! Code kann sich in Releases einschleichen, deren Funktionen markiert sind,noexcept
und zur Laufzeit (dh bei Kundenstandorten) werden Verstöße erkannt. Ich meinte die Compiler - Garantien Code zu generieren , die nicht werfen Ausnahmen in dem ersten Platz.throws()
ist, muss der Stapel, wenn eine Ausnahme ausgelöst wird, bis zum Umfang dieser Funktion abgewickelt werden (damit alle automatischen Variablen in der Funktion zerstört werden). An diesem Punktterminate()
wird (viaunexpected()
) aufgerufen . Wenn eine Funktion markiert ist undnoexcept
dann eine Ausnahme ausgelöst wird, wird terminate aufgerufen (das Abwickeln des Stapels ist ein implementierungsdefiniertes Detail).noexcept
wird beim Kompilieren nicht überprüft.Wenn eine Funktion deklariert wird
noexcept
oderthrow()
versucht, eine Ausnahmeterminate
auszulösen, besteht der einzige Unterschied darin, dass man aufruft und die anderen Aufrufeunexpected
und der letztere Stil der Ausnahmebehandlung effektiv veraltet sind.quelle
throw()
/noexcept
hat, stellen Sie bei der Überprüfung der Kompilierungszeit sicher, dass auch ein Overrider vorhanden ist.std::unexpected()
wird von der C ++ - Laufzeit aufgerufen, wenn eine dynamische Ausnahmespezifikation verletzt wird: Eine Ausnahme wird von einer Funktion ausgelöst, deren Ausnahmespezifikation Ausnahmen dieses Typs verbietet.std::unexpected()
kann auch direkt aus dem Programm aufgerufen werden.Ruft in beiden Fällen
std::unexpected
den aktuell installierten aufstd::unexpected_handler
. Der Standardstd::unexpected_handler
nenntstd::terminate
.quelle