exception-safety

___ answer25667585 ___

Ich bin in ähnlicher Weise von diesem Problem verblüfft.

Soweit ich das beurteilen kann, besteht das beste aktuelle Idiom darin, den Pass-by-Value in ein Paar von Pass-by-Referenzen aufzuteilen.

%Vor%

Natürlich könnten Teile des Arguments vor der Ausnahme verschoben worden sein. Das Problem wird an alle Aufrufe von %code% weitergegeben.

Ich hatte eine Inspiration, ein Objekt zu entwickeln, das sich auf bestimmte Ausnahmen zurückverlagert, aber das ist eine Lösung für ein bestimmtes Problem am Horizont in einem meiner Projekte. Es könnte am Ende zu spezialisiert oder gar nicht machbar sein.

    
___ qstntxt ___

Ich habe eine Funktion, die auf einem großen Datenblock arbeitet, der als Sink-Argument übergeben wird. Mein %code% -Typ ist bereits C ++ 11-fähig und kommt mit voll funktionsfähigen Move-Konstruktor- und Move-Assignment-Implementierungen, so dass ich wegkommen kann, ohne das verdammte Ding kopieren zu müssen:

%Vor%

Das alles funktioniert einwandfrei. Meine Verarbeitungsfunktion kann jedoch gelegentlich zur Laufzeit fehlschlagen, was zu einer Ausnahme führt. Das ist nicht wirklich ein Problem, da ich einfach Sachen reparieren und wiederholen kann:

%Vor%

Natürlich wird das nicht funktionieren.

Da ich meine Daten in die Verarbeitungsfunktion verschoben habe, wird %code% nicht mehr verwendbar sein, wenn ich im Ausnahmebehandler angekommen bin.

Das droht meine Begeisterung für die Weitergabe von Sinkargumenten als Wert zu reduzieren.

Hier ist also die Frage: Wie geht es im modernen C ++ - Code mit einer solchen Situation? Wie kann der Zugriff auf Daten abgerufen werden, die zuvor in eine Funktion verschoben wurden, die nicht ausgeführt werden konnte?

Sie können die Implementierung und die Schnittstellen für %code% und %code% beliebig ändern. Die endgültige Lösung sollte jedoch versuchen, Nachteile gegenüber dem ursprünglichen Code in Bezug auf Effizienz und Benutzerfreundlichkeit zu minimieren.

    
___ tag123c11 ___ C ++ 11 ist eine 2011 verabschiedete Version des C ++ - Sprachstandards. Sie hat viele Änderungen und Ergänzungen in der Kernsprache sowie der verbesserten und erweiterten C ++ - Standardbibliothek vorgenommen. ___ tag123idioms ___ Ein Programmier-Idiom ist eine Möglichkeit, eine Beschränkung der Programmiersprache zu überwinden und / oder häufig verwendeten Code mit einem Zweck zu schreiben, der von einer wörtlichen Bedeutung des Codes getrennt ist. Außerdem ist ein Idiom eine bevorzugte Art, Code zu schreiben, wenn es mehr als einen offensichtlichen Weg gibt, dies zu tun. ___ tag123movesemantics ___ Move semantics ist eine Programmiersprachenfunktion, die es ermöglicht, einen Kopiervorgang durch einen effizienteren "move" zu ersetzen, wenn das Quellobjekt ein temporäres oder ein anderweitig ablaufendes Objekt ist. ___ tag123exceptionssafety__ Hilf uns dabei, dieses Wiki zu bearbeiten ___ tag123c ___ C ++ ist eine universelle Programmiersprache. Es wurde ursprünglich als Erweiterung von C entworfen und behält eine ähnliche Syntax, ist aber jetzt eine komplett andere Sprache. Verwenden Sie dieses Tag für Fragen zu Code, der mit einem C ++ - Compiler kompiliert werden soll. ___ qstnhdr ___ Sink-Argumente und Verschieben von Semantiken für Funktionen, die fehlschlagen können (starke Ausnahmesicherheit) ___ answer25890161 ___

Anscheinend wurde dieses Thema auf der letzten CppCon 2014 lebhaft diskutiert. Herb Sutter fasste den letzten Stand der Dinge in seinem Abschlussreferat zusammen: Zurück zu den Grundlagen! Grundlagen des modernen C ++ - Stils (Folien) .

Seine Schlussfolgerung ist ganz einfach: Verwenden Sie keinen Pass-by-Wert für Sink-Argumente.

Die Argumente für die Verwendung dieser Technik an erster Stelle (wie von Eric Niebler's Meeting C ++ 2013 Keynote C ++ 11 Bibliotheksdesign (Folien) ) scheint von den Nachteilen aufgewogen zu werden. Die ursprüngliche Motivation für die Weitergabe von Sinkargumenten als Wert war, die kombinatorische Explosion für Funktionsüberlastungen zu beseitigen, die sich aus der Verwendung von %code% / %code% ergibt.

Leider scheint dies eine Reihe von unbeabsichtigten Konsequenzen zu haben. Eines davon sind potenzielle Effizienznachteile (hauptsächlich aufgrund unnötiger Pufferzuweisungen). Der andere ist das Problem mit Ausnahme Sicherheit von dieser Frage. Beide werden in Herb's Gespräch besprochen.

Herbs Schlussfolgerung ist, nicht Pass-by-Value für Sink-Argumente zu verwenden, sondern stattdessen auf separate %code% / %code% (wobei %code% der Standardwert und %code% reserviert ist) für die wenigen Fälle, in denen eine Optimierung erforderlich ist).

Dies entspricht auch der Antwort von @ Potatowatter . Durch Übergabe des Sink-Arguments über %code% können wir möglicherweise die tatsächliche Verschiebung der Daten vom Argument auf einen Punkt verschieben, an dem wir keine Garantie geben können.

Mir gefiel die Idee, Sinkargumente nach Wert zu übergeben, aber es scheint, dass es in der Praxis nicht so gut funktioniert, wie alle erhofft haben.

    
___
2
Antworten

Sink-Argumente und Verschieben von Semantiken für Funktionen, die fehlschlagen können (starke Ausnahmesicherheit)

Ich habe eine Funktion, die auf einem großen Datenblock arbeitet, der als Sink-Argument übergeben wird. Mein BigData -Typ ist bereits C ++ 11-fähig und kommt mit voll funktionsfähigen Move-Konstruktor- und Move-Assignment-Implementierungen, s...
04.09.2014, 13:53