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
#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").