Lass andere arbeiten

Die beste Art von Arbeit ist ja immer die, die man nicht selbst machen muss. Daher habe ich das Beispiel vom letzten Mal umgebaut, um den Hauptanteil der Arbeit von der Standardbibliothek erledigen zu lassen. Hat eigentlich nur Vorteile: man muss selbst weniger tun und hat damit natürlich auch weniger Möglichkeiten Fehler zu machen.

Video

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
 
int main()
{
    std::vector<int> v;
    v.push_back(2);
    v.push_back(7);
    v.push_back(4);
 
    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cerr, "\n"));
     
    std::list<std::string> l;
    l.push_back("Eins");
    l.push_back("Zwo");
    l.push_back("Drei");
     
    std::copy(l.begin(), l.end(), std::ostream_iterator<std::string>(std::cerr, "\n"));
}

Erklärung

Um unsere Datenstrukturen auf std::cerr auszugeben, müssen wir nicht zwingend eine eigene Funktion schreiben. Die Standardbibliothek stellt uns schon alles zur Verfügung. Die beiden Zutaten hier sind einerseits der vorhandene std::copy-Algorithmus und andererseits std::ostream_iterator. std::copy(start, end, target) ist ein immer mal wieder gebrauchter Algorithmus: er kopiert den Inhalt des Bereiches [start, end) in den Bereich, auf dessen erstes Element target zeigt. Dabei ist es dem Algorithmus komplett egal, wie die einzelnen Bereiche aussehen. Der Trick, der Details hier verbirgt, sind geeignete Iteratoren. Einen etwas spezielleren sehen wie mit std::ostream_iterator. Dieses Template verpackt einen beliebigen Ausgabestrom (in unserem Fall std::cerr) in einen Iterator, so dass man ihn in die Welt der Standardalgorithmen integrieren kann. Dabei schreibt das Iteratorobjekt jedesmal, wenn es zugewiesen wird, das übergebene Datum auf den konfigurieren Ausgabestrom. Haben wir beim Erzeugen des Iterators ein Trennzeichen angegeben, so wird das auch noch mit ausgegeben (in unserem Fall "\n").