The C++ Programming Language (Second edition)Thanks to all who sent me comments. I am only able to correct minor problems. Sorry. Adding new sections, examples, and introducing new topics can only be done for new editions and not between printings.
Comments of all sorts both on the book and this errata are welcome.
- Bjarne Stroustrup (bs@research.att.com)I have posted some of this errata before, but I thought it useful for some to have it all together. In several case, I have simply listed the corrected text (leaving you to find the original error). In other cases I have used the old ed substitute syntax: s/old/new/
and add { } around case DIV on page 78 and case LP on page 79.
class Z2 : public Y2 { void f(Y1*, Y2*, Y3*); }; class Y3 : private X { void f(Y1*, Y2*, Y3*); };
void copy(expr* s, int deep = 0); void expr::copy(expr* s, int deep) left = s->left->clone(1); right = s->right->clone(1); class conditional : public expr { void copy(conditional* s, int deep = 0); void conditional::copy(conditional* s, int deep)
char& string::operator[](int i) { if (i<0 || strlen(p->s)<i) error("index out of range"); if (p->n>1) { // clone to maintain value semantics srep* np = new srep; np->s = new char[ strlen(p->s)+1 ]; strcpy(np->s, p->s); p->n--; p = np; } return p->s[i]; }
template<class T> T* Slist_iter<T>::operator()() { Tlink<T>* lnk = (Tlink<T>*) slist_base_iter::operator()(); return lnk ? &lnk->info: 0; }
void f(name* n) { Islist<name> lst1; Slist<name> lst2; lst1.insert(n); lst2.insert(n); // ... Islist_iter<name> iter1(lst1); const name* p; while (p=iter1()) { Slist_iter<name> iter2(lst2); const name* q; while (q=iter2()) { if (p == q) cout << "found " << *p << '\en'; } } }
template<class T, class Comp> class Sort { public: static void sort(Vector<T>&); }; template<class T, class Comp> void Sort<T,Comp>::sort(Vector<T>& v) { unsigned int n = v.size(); for (int i=0; i<n-1; i++) for (int j=n-1; i<j; j--) if (Comp::lessthan(v[j],v[j-1])) { T temp = v[j]; v[j] = v[j-1]; v[j-1] = temp; } }We can now select the appropriate sort() by qualifying it with a Sort class with appropriate element and comparator types:
void f(Vector<int>& vi, Vector<String>& vc, Vector<int>& vi2, Vector<char*>& vs) { Sort< int,Comparator<int> >::sort(vi); Sort< String,Comparator<String> >::sort(vc); Sort< int,Comparator<int> >::sort(vi2); Sort< char*,Comparator<char*> >::sort(vs); }This last variant is a powerful model for composition of code from separate parts. The example can even be further simplified by using the comparator type as the only template argument:
template<class Comp> class Sort { public: class Comp::T; // Comp must have a member type T static void sort(Vector<Comp::T>&); };The sort() function will sort any Vector that Comp can compare elements of:
void f(Vector<int>& vi, Vector<String>& vc, Vector<int>& vi2, Vector<char*>& vs) { Sort< Comparator<int> >::sort(vi); Sort< Comparator<String> >::sort(vc); Sort< Comparator<int> >::sort(vi2); Sort< Comparator<char*> >::sort(vs); }This implies that the comparator must give a name to its element type
template<class T> class Comparator { public: typedef T T; // define Comparator<T>::T static int lessthan (T& a, T& b) { return a < b; } // ... };so that Sort<Comp>::sort() can refer to the element type as Comp::T.
s/Omanip& m/Omanip_int& m/
s/_set_// twice