C++1y: Quoted Strings

von Hubert Schmid vom 2014-02-09

Hinter dem qualifizierten Bezeichner std::quoted werden sich in der kommenden C++-Version drei überladene Funktionstemplates verbergen. Diese Erweiterung ist als Quoted Strings bekannt und erfüllt eigentlich nur einen einzigen Zweck: Sie erleichtert Anfängern den Einstieg in C++.

Das Problem ist einfach umrissen: Eigentlich sollte in der Ausbildung der Schwerpunkt auf dem Umgang mit Datenstrukturen liegen. Doch leider wird dieses Vorgehen durch die umständliche Ein-/Ausgabe überlagert – insbesondere wenn Zeichenketten mit beliebigen Steuerzeichen involviert sind. Denn C++ bot bisher keine einfache Möglichkeiten für Serialisierung und Deserialisierung an. Ein Beispiel einer entsprechenden Datenstruktur ist im folgenden Listing zu sehen.

struct employee { int id{}; std::string name{}; std::string department{}; int salary{}; };using employees = std::vector<employee>;

Für produktive Anwendungen werden üblicherweise Datenbanken verwendet, deren Zugriffsbibliotheken hinreichend von den technischen Details abstrahieren. Für Ausbildungszwecke wäre dagegen eine einfache Persistenz wünschenswert. Die Funktionen für Stream Insertion und Extraction sehen zwar grundsätzlich diese Möglichkeit vor, scheitern jedoch bereits an Zeichenketten mit Leerzeichen. Die überladenen Funktionen std::quoted adressieren genau diese Lücke. Die Serialisierung sieht damit beispielsweise wie folgt aus.

auto& operator<<(std::ostream& os, const employee& employee) { os << ' ' << employee.id << ' ' << std::quoted(employee.name) << ' ' << std::quoted(employee.department) << ' ' << employee.salary; return os; }void dump(std::ostream& os, const employees& employees) { using iterator = std::ostream_iterator<employee>; std::copy(employees.begin(), employees.end(), iterator{os}); }

Die Deserialisierung erfolgt analog. In diesem Fall stellt std::quoted die ursprüngliche Zeichenkette wieder her. Dabei können Fehler mittels is.bad() und is.fail() behandelt werden.

auto& operator>>(std::istream& is, employee& result) { employee employee; is >> employee.id >> std::quoted(employee.name) >> std::quoted(employee.department) >> employee.salary; result = std::move(employee); return is; }auto load(std::istream& is) { using iterator = std::istream_iterator<employee>; return employees{iterator{is}, iterator{}}; }

Für andere Einsatzszenarien ist std::quoted dagegen weitgehend ungeeignet, da die gewählte Maskierung sehr rudimentär ist. Der Nutzen für die Ausbildung und damit auch für C++ insgesamt ist jedoch nicht zu unterschätzen. Denn eine geringe Einstiegshürde unterstützt die Verbreitung.