2014-11-13 15 views
6

Wenn ich die Container Anforderungen auf cppreference es Listen Destructible als eine Voraussetzung für value_type. Dies scheint zu implizieren, dass Destruktoren von Containerelementen nicht werfen können.Können die Elemente in einem std :: vector einen werbenden Destruktor haben?

Ich konnte nicht finden, ein Zitat für diese Anforderung in der C++ 14-Standard (nicht in älteren Versionen geschaut). Das einzige, was ich finden kann ist, dass value_typeErasable sein muss, was keine Ausnahmesicherheit impliziert.

Also meine Frage ist, können die Elemente in einem std::vector einen Wurf Destruktor haben? Wenn nicht, welcher Abschnitt des Standards verbietet es?


S.S .: Keine Sorge, ich habe nicht vor, Typen mit Wurf-Destruktoren zu erstellen. Ich schreibe gerade eine standardkonforme Implementierung und versuche, die Ausnahmesicherheit richtig zu machen.

+0

Tabelle 14 in der C++ 11 Standard sagt das gleiche, was Ihre cppreference von Destructible sagt: "keine Ausnahme wird propagiert". –

+3

cppreference aktualisiert, um mit Tabelle 96 übereinzustimmen, tut mir leid, dass Ihre Frage veraltet ist – Cubbi

+0

@TonyD Meine Frage geht nicht um Zerstörbar, es geht um 'std :: vector'. – orlp

Antwort

4

N4140 [res.on.Funktionen]/2 heißt es:

Insbesondere werden die Effekte in den folgenden Fällen nicht definiert:

(2,1) - für Ersatzfunktionen (18.6.1), wenn die installierte Ersatzfunktion der nicht implementiert Semantik des anwendbaren Erforderlichen Verhaltens: Absatz.

(2,2) - für Handler-Funktionen (18.6.2.3, 18.8.3.1, D.11.1), wenn die installierte Handler-Funktion, die Semantik des anwendbaren Required Verhaltens nicht umsetzen wird: Absatz

(2,3) - für Typen, die als Template-Argumente beim Instanziieren einer Template-Komponente verwendet werden, wenn die Operationen auf dem Typ nicht die Semantik der anwendbaren Anforderungsunterklausel (17.6.3.5, 23.2, 24.2, 26.2) implementieren. Operationen mit solchen Typen können einen Fehler melden, indem sie eine Ausnahme auslösen, sofern nicht anders angegeben.

(2.4) - Wenn eine Ersatzfunktion oder eine Handlerfunktion oder ein Destruktorbetrieb über eine Ausnahme beendet wird, sofern nicht ausdrücklich im entsprechenden Erforderlichen Verhalten: Absatz.

(2.5) - wenn ein unvollständiger Typ (3.9) als Vorlagenargument verwendet wird, wenn eine Vorlagenkomponente instanziiert wird, es sei denn, für diese Komponente ist dies ausdrücklich erlaubt.

die ein bisschen dunkel, aber spart eine Menge Platz, die sonst verschwendet würden, Aussagen in der Bibliotheks Klauseln „T muß die zerstörbaren Anforderungen erfüllen“.

Bemerkenswerterweise bedeutet dies nicht, dass Elemente eines std::vector keinen werbenden Destruktor haben können; es bedeutet nur, dass der Destruktor niemals werfen darf, wenn er aus der Standardbibliothek aufgerufen wird. So z.B. Dieses Programm ist konform:

1

Ja. & Dolch; Die Norm sagt dies im allgemeinen Anforderungen:

[C++11: §23.2.1/10]:

Sofern nicht anders angegeben (siehe 23.2.4.1, 23.2.5.1, 23.3.3.4 und 23.3.6.5 ) alle Arten Behälter definiert in Diese Klausel erfüllt die folgenden zusätzlichen Anforderungen:

- keine Erase() -, clear() -, pop_back() - oder pop_front() -Funktion löst eine Ausnahme aus.

Verwenden der clear Funktion als Beispiel (da sie nicht eine Ausnahme von der allgemeinen Anforderung ist) es hat die folgenden Anforderungen:

Zerstört alle Elemente in einem. Deklariert alle Verweise, Zeiger und Iteratoren, die sich auf die Elemente von a beziehen, und kann den UI-Iterator ungültig machen. Beitrag: a.empty() kehrt true

was bedeutet, dass sie im wesentlichen die std::allocator_traits<Alloc>::destroy auf alle Elemente aufruft. Welche Delegierten sind zu t->~T(), wenn a.destroy(t) nicht verfügbar ist. Doch dies garantiert implizit, dass weder a.destroy(t) noch t->~T() sollte werfen, weil es clear ist stark noexcept Spezifikation verstoßen werde:

// § 23.3.6.1 
void clear() noexcept; 

durch Abzug So konnten wir behaupten, dass Destruktoren werfen können, aber sie müssen durch einen Mechanismus unterdrückt werden, als wickeln sie sie in einen try-catch-Block.

& dolch ;: Bei weiterer Überprüfung scheint es, dass Destruktoren können werfen, aber die Ausnahmen müssen unterdrückt werden, wie in den Kommentaren unten angegeben.

+1

Aber das verbietet nicht 'void clear() noexcept {try {_ActualClear(); } catch (...) {}} Implementierung, oder? –

+0

Wie @Joker_vD sagt, "noexcept" ist keine Garantie dafür, dass die Ausführung einer Funktion nicht dazu führen kann, dass eine Exception ausgelöst wird, es ist eine Garantie dafür, dass von dieser Funktion keine Ausnahmen ausgegeben werden. – Casey

+0

So könnte ein benutzerdefinierter Allokator eine Ausnahme unterdrücken "destroy", so dass "value_type" einen werbenden Destruktor haben kann .. sollte nicht Ihre erste Zeile dann "Ja" sagen? – Cubbi