Wie im Vorwort angekündigt, erwähnen wir hier auf dieser Seite diejenigen namentlich, die uns einen Fehler (gleichgültig welcher Art) zuerst mitteilen. Seit Erscheinen der 2. Auflage wird diese Seite nicht mehr gepflegt.
Die meisten Aufgaben beschäftigen sich mit Themen, die über das im Text Gesagte hinausgehen.
Als es das Schlüsselwort noch nicht gab, ...
... (wobei a
wieder ein Objekt des Typs
Feld<int>
ist) ...
isPrim
(Olaf Raeke): bool isPrim(unsigned int z) { const unsigned int stop = sqrt(static_cast<double>(z)); for (unsigned int i = 2; i <= stop; ++i) if (z % i == 0) return false; return true; }
... wird ... eine Ausnahme des Typs bad_alloc
ausgeworfen, ...
iterator erase(iterator q1, iterator q2)
(Olaf Raeke):
... Es wird ein Iterator zurückgegeben, der auf das Element verweist, auf das vor dem Löschen q2
zeigte. ...
Um Speicher freizugeben, kann die Anweisung v.swap(vector<int>(v));
benutzt werden, wobei die
enthaltenen Elemente erhalten bleiben.
Warum sind im folgenden Programmfragment die Definition von c
sowie der Vergleich von a
und b
fehlerhaft?
priority_queue<int> a; priority_queue<int, vector<int>, greater<int> > b; greater<int> g; priority_queue<int> c(g); // Fehler a = b;
Man beachte, dass forward_iterator_tag
nur von input_iterator_tag
und
nicht auch von output_iterator_tag
abgeleitet wurde. Der Grund dafür ist,
daß Forward- und Output-Iteratoren sich bezüglich einer Feinheit
unterscheiden. Ein Forward-Iterator fi
kann sich normalerweise nur über
einen begrenzten Bereich bewegen, daher hat eine typische while-
Schleife hier die Form
while(fi != end) *fi++ = x;
wobei end
ein Iterator ist, der das
Bereichsende markiert, und x
ist ein zuweisungskompatibler Wert. Für
Output-Iteratoren sind Vergleiche dagegen nicht definiert, so daß derartige Schleifen
für sie nicht formulierbar sind. Andererseits kann man mit ihnen quasi beliebig viele Werte
schreiben, ohne ein Bereichsende zu prüfen, etwa in der Form while(true) { *oi++ = x;
... }
. Dieses Vorgehen ist wiederum für Forward-Iteratoren nicht definiert.
distance
(SK):
while (first != last) { ++n; ++first; }
const int f[] = { 1, 2, 3, 4 };
find_end
(Olaf Raeke):
... Als Aufwand ergeben sich deshalb höchstens (last2
- first2) * (last1 - first1 - (last2 - first2) + 1)
Vergleiche bzw. Aufrufe von pred.
count
(Olaf Raeke):
Beim Einsatz von count
muß für den Typ
T
der Vergleichsoperator ==
definiert sein.
search_n
(Olaf Raeke, SK):
Der Aufwand beträgt höchstens (last - first) *
count
Vergleiche bzw. Aufrufe von pred
.
replace_copy_if
(Olaf Raeke): template<class InputIterator, class OutputIterator, class Predicate, class T> OutputIterator replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value);
unique_copy
(Olaf Raeke):
Für Forward-Iteratoren kann der Funktionsrumpf für
unique_copy
ohne Prädikat wie folgt definiert werden:
if (first == last) return result; *result = *first; while (++first != last) if (*result != *first) *++result = *first; return ++result;
Für den Einsatz von Prädikaten ist mehr Aufwand zu treiben, da der Wert von
*result
hier i.a. nicht mit *(first - 1)
übereinstimmt.
unique.cpp
(Olaf Raeke,
SK): [f, f + 10) = 1 3 7 1 2 7 1 1 2 2 [f, z) = 1 3 7 1 2 [f, z) = 1 3 7 2
Für die letzte Zeile werden derzeit auch andere Ergebnisse diskutiert, da die
Funktionsspezifikation im Standard diesen Fall bisher nicht berücksichtigt. Um portable
Programme zu erhalten, sollten für unique
deshalb besser nur Prädikate
eingesetzt werden, die prüfen, ob zwei Elemente äquivalent sind.
rotate_copy
(Olaf Raeke):
rotate_copy
kopiert die Elemente des Bereichs [middle, last)
in den
Bereich [result, result + (last - middle))
und
[first, middle)
nach [result + (last - middle),
result + (last - first))
. Dies entspricht einer Rotation gegen den Uhrzeigersinn, wobei
für alle n
von 0
bis last - first - 1
die Zuweisung
*(result + n) = *(first + (n + (middle - first)) % (last - first))
ausgeführt wird.
Wenn ausreichend Speicherplatz zur Verfügung steht, benötigt der Algorithmus dazu
N log(N) Vergleiche, sonst N (log(N))2, wobei N = last -
first
ist.
Da die assoziativen Container nur über Bidirectional-Iteratoren verfügen,
sollten die Algorithmen lower_bound
,
upper_bound
und equal_range
für sie nicht aufgerufen werden. Statt
dessen stellen die assoziativen Container speziell angepaßte Elementfunktionen zur
Verfügung.
includes
(Olaf Raeke):
Das Ergebnis von includes
ist true
, wenn für jedes Element des
Bereichs [first2, last2)
ein äquivalentes Element im Bereich [first1,
last1)
enthalten ist. Der Funktionsrumpf könnte z.B. wie folgt definiert sein:
lexicographical_compare
(SK):
Es werden höchstens 2 * min((last1 - first1), (last2
- first2))
Vergleiche benötigt.
adjacent_difference
(SK):
Der Rückgabewert ist result + (last - first)
.
partial_sum
(SK):
Der Rückgabewert ist result + (last - first)
.
Hier allerdings bevorzugt in der Nähe der Adresse
u
.
Diesen Satz streichen: deallocate
wirft keine Ausnahmen aus.
Zur Initialisierung des Stringobjekts s
mit einer Zeichenkette wird ein entsprechender Konstruktor benutzt, ...
Da der Konstruktor ein Argument des Typs const
char*
erwartet, ...
class Kunde { public: Kunde(const string& name); // ... };
Die Streamklassen der Standardbibliothek setzen intern Puffer (Buffer) ein, die in der
Header-Datei <streambuf>
definiert sind.
Per Vorgabe ist keines der Bits für die Ausrichtung (internal
,
left
oder right
) gesetzt. In diesem Fall verhält sich ein Stream so,
als ob right
gesetzt wäre. In der Tabelle sollte dies durch * bei
right
gekennzeichnet werden.
Setzt zusätzlich zu den bereits eingestellten Flags die
Flags, die im Parameter fmtfl
gesetzt sind, und liefert die vorherige Einstellung
aller Flags.
bool fail() const { return rdstate() & (failbit | badbit); }
Eigentlich sollte diese Funktion nur prüfen, ob failbit
gesetzt ist. Im
C++-Standard heißt es dazu in einer Fußnote: "Checking badbit
also for fail()
is historical practice."
Wie üblich erzeugt der Konstruktor ein Ausnahmeobjekt, das durch den Stringparameter
msg
beschrieben wird. Ein Aufruf der Funktion what
liefert
msg.c_str()
.
Nach dem Öffnen einer Datei ...
ofstream out(dateiname, ios_base::out |
ios_base::trunc);
Durch einen Aufruf der nicht const
deklarierten Elementfunktion str
kann man später einen neuen String zuweisen.
... mit der Funktion DM2double
wieder zurück in einen double
.
Die Hauptaufgabe eines Auto-Pointers besteht darin, ...
Eine Initialisierung der Art bitset<5> b6("1101");
ist
nicht möglich, weil der Konstruktor als Member-Template
definiert ist und deshalb eine exakte Übereinstimmung von Parameter- und Argumenttyp vorliegen
muß. Dies war sicherlich nicht beabsichtigt, und es kann damit gerechnet werden, daß
die Klasse zukünftig um einen Konstruktor für den Typ const char*
erweitert
wird. Bis dahin muß man sich wohl oder übel mit bitset<5>
b6(string("1101"));
behelfen. Aus dem gleichen Grund sind Zuweisungen der Art
b6 = "11010"
unzulässig.
template<class T> inline T arg(const complex<T>& c) { return atan2(imag(c), real(c)); }
has_denorm
(SK):
static const float_denorm_style has_denorm =
denorm_absent;
Diese vier Konstruktoren definieren Konversionen vom jeweiligen
Parametertyp in ein valarray
.
strcmp
ist eine zweistellige Funktion des Typs ...
template<class T> struct Schaltjahr : public unary_function<T, bool> { bool operator()(T jahr) const { return (jahr % 4 == 0) && ((jahr % 100 != 0) || (jahr % 400 == 0)); } };
Bedauerlicher Weise nicht! Bei der Instanzierung der Template-Funktion resultiert für den
ersten Parameter der Typ const char (&)[5]
, der nicht kopierbar ist.
c
kann nur mit einem Vergleichsobjekt des Typs
less<int>
initialisiert werden. Die Typen von a
und
b
stimmen nicht überein, weil a
per Vorgabe das Vergleichsobjekt
less<int>
benutzt und b
statt dessen
greater<int>
.
Die Deklaration von m3
ist fehlerhaft und somit zu streichen.
Mit ... läßt sich das Problem umgehen.
Dabei ergibt sich ein Konflikt, weil string
in der Header-Datei "kunde.h"
als Klasse und in <string>
als typedef
deklariert ist.
Das folgende Programm zeigt die Datei, deren Name als Kommandozeilenparameter übergeben wird, an.
Falls Sie etwas entdeckt haben, würden wir uns freuen, wenn Sie uns dies mitteilen: Fehlermeldung