2015-01-18 14 views
9

Warum bietet std::runtime_error keinen Konstruktor an, der eine std::string&& akzeptiert? Betrachtet man the constructors for std::string, hat es einen Move-Konstruktor, aber die noexcept Spezifikation ist nur für C++ 14, nicht für C++ 11. War das ein Fehler, eine Frist, die verpasst wurde oder fehlt mir etwas?move constructor für std :: runtime_error

+0

Wenn 'std :: runtime_error' einen Konstruktor hat, der' std :: string && 'nimmt, wäre es sicherlich kein Move-Konstruktor. Ein Move-Konstruktor würde 'std :: runtime_error &&' übernehmen. –

+0

Ich bin mir nicht sicher, ob ich folge: Von Anfang an zu urteilen scheint es sich bei deiner Frage um 'runtime_error' zu handeln, aber dann wechselst du zu' std :: string'. Welchen Punkt versuchst du zu machen? –

+0

@AndyProwl: 'std :: runtime_error' kann zur Zeit aus einem 'const std :: string 'oder aus einem' const char * was_arg' aufgebaut werden. Er fragt, warum er nicht aus einer 'std :: string &&' konstruiert werden kann. –

Antwort

14

explicit runtime_error(string&&);

existiert nicht, nur weil es jede Optimierung nicht bieten würde.

Wie sich herausstellt, speichert ein C++ 11-konformes runtime_error intern std::string nicht. Der Grund dafür ist, dass die Kopiermitglieder von runtime_error keine Ausnahmen auslösen dürfen. Andernfalls könnte die falsche Ausnahme ausgelöst werden, wenn der Compiler das Ausnahmebedingungsobjekt kopiert.

Dies bedeutet, dass runtime_error eine nicht veränderbare Referenzzählung speichern muss. C++ 11 verbietet jedoch die COW-Implementierung für std::string. Implementierungen von std::string sind zu einer "Short-String-Optimierung" übergegangen, die bei der Copy-Konstruktion zugewiesen werden muss, wenn die Länge des Strings über dem "Short-Limit" liegt. Und es gibt keine Begrenzung für die Länge der Strings, die für die Konstruktion eines runtime_error verwendet werden.

So effektiv C++ 11 (und nach vorn) enthält zwei Implementierungen von Strings:

  1. std::string: Dies ist typischerweise ein kurzes String-optimierte Typ mit einem Copy-Konstruktor und Zuordnung kopieren, die in der Lage ist Ausnahmen werfen.

  2. std::runtime_error: Dies ist (oder hält) eine unveränderliche Referenz gezählte Zeichenfolge. Dies wird niemals auf Kopierkonstruktion oder Kopierzuweisung übertragen.

Und

explicit runtime_error(string&&);

kann nie (effizient) Übertragungsressourcen vom "Typ 1" Zeichenfolge an den "Typ 2" string.

+1

Wie würde die Typ 2-Saite aussehen, die nicht von Interesse ist? (Wenn es ein schwarzer, versteckter, implementierungsdefinierter interner Typ ist, dann ist das eine ausreichende Antwort.) –

+5

Es könnte wie die nicht-mutierenden Teile eines C++ 03 COW-basierten 'std :: string' aussehen. Tatsächlich hat libC++ genau das getan. Sein Typ 2-String hat einen ABI, der mit dem gcc-4.2 "std :: string" identisch ist, so dass 'runtime_error' aus libC++ geworfen und mit libstdC++ (und umgekehrt), * innerhalb derselben Anwendung * abgefangen werden kann. –

+0

Warum möchten Sie das tun? –

Verwandte Themen