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
Antwort
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:
std::string
: Dies ist typischerweise ein kurzes String-optimierte Typ mit einem Copy-Konstruktor und Zuordnung kopieren, die in der Lage ist Ausnahmen werfen.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.
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.) –
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. –
Warum möchten Sie das tun? –
- 1. Move Constructor aufrufende Basisklasse Move Constructor
- 2. Move Constructor ohne Zeiger
- 3. Move constructor und double delete
- 4. Unterschied: std :: runtime_error vs std :: exception()
- 5. Verwirrt über std :: runtime_error vs. std :: logic_error
- 6. Wie vererbt man von std :: runtime_error?
- 7. Wann wird Move Constructor aufgerufen?
- 8. Wie erzwinge std :: sort, um move constructor und move-assignment zu verwenden?
- 9. Sind std :: move und std :: copy identisch?
- 10. Fehler beim Abfangen von std :: runtime_error als std :: exception
- 11. Warum werden Move Constructor und Move-Zuweisungsoperator aufgerufen und nicht kopiert?
- 12. Kopie vs Std :: move für Ints
- 13. Returning std :: move (f) in std :: for_each
- 14. Mischen std :: move() und std :: Thread
- 15. std :: vector :: emplace_back und std :: move
- 16. Sind der Kopierkonstruktor und die Kopierzuordnung von std :: runtime_error noexcept?
- 17. Ist `std :: move 'hier notwendig?
- 18. Wurf std :: runtime_error innerhalb OpenMP Region stürzt das Programm
- 19. Implementieren Sie move semantics für meinen eigenen std :: vector
- 20. Ausführen einiger Operationen auf Std :: move (x)
- 21. fehlgeschlagen C++ Primer über std :: move()
- 22. Warum benötigt dies eine explizite std :: move?
- 23. Warum elision nicht mit std :: move arbeiten?
- 24. Ist `x = std :: move (x)` undefiniert?
- 25. std :: move auf eine Variable, die bereits T &&
- 26. Clang Fehler: Hinweis: Kandidat Konstruktor (der implizite Move Constructor) nicht durchführbar:
- 27. Gibt es eine Möglichkeit zu std :: move std :: string in std :: stringstream
- 28. Constructor
- 29. Constructor Ausgabe
- 30. Verschieben Constructor - ungültiger Typ für notleidende Konstruktor VS 2013
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. –
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? –
@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. –