Download - GDC Roadtrip Dec 1999 Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee
GDC Roadtrip Dec 1999
Embracing the C++ STL:Embracing the C++ STL:Why Angle Brackets areWhy Angle Brackets areGood for YouGood for You
Pete IsenseePete Isensee
GDC Roadtrip Dec 1999
IntroductionIntroduction STL Background & HistorySTL Background & History Key ConceptsKey Concepts Containers, Iterators and Containers, Iterators and
AlgorithmsAlgorithms Efficiency and Thread SafetyEfficiency and Thread Safety Tips and TricksTips and Tricks
GDC Roadtrip Dec 1999
GoalsGoals STL NewbieSTL Newbie
– Convince you that it’s a “good thing”Convince you that it’s a “good thing”– Help you avoid common mistakesHelp you avoid common mistakes
STL JunkieSTL Junkie– Add new STL techniques to your Add new STL techniques to your
toolboxtoolbox– Tricks and tipsTricks and tips
GDC Roadtrip Dec 1999
PreliminariesPreliminaries Microsoft Visual C++ 6.0Microsoft Visual C++ 6.0 Dinkumware STL implementationDinkumware STL implementation Benchmarks on Pentium III - Benchmarks on Pentium III -
550MHz550MHz Performance graphs show Performance graphs show relativerelative
performance – taller is better!performance – taller is better!
GDC Roadtrip Dec 1999
HistoryHistory Alex Stepanov & Meng Lee, based Alex Stepanov & Meng Lee, based
on earlier work by Stepanov & on earlier work by Stepanov & MusserMusser
Proposed to C++ committee late ‘93Proposed to C++ committee late ‘93 HP version released ‘94HP version released ‘94 Accepted into Standard summer ‘94Accepted into Standard summer ‘94 Standard froze ‘97, ratified ‘98Standard froze ‘97, ratified ‘98
GDC Roadtrip Dec 1999
AdvantagesAdvantages StandardizedStandardized Thin & efficientThin & efficient Little inheritance; no virtual Little inheritance; no virtual
functionsfunctions Small; easy to learnSmall; easy to learn Flexible and extensibleFlexible and extensible Naturally open sourceNaturally open source
GDC Roadtrip Dec 1999
DisadvantagesDisadvantages Template syntaxTemplate syntax Difficult to read & decipherDifficult to read & decipher Poor or incomplete compiler Poor or incomplete compiler
supportsupport Code bloat potentialCode bloat potential No constraints on template typesNo constraints on template types Limited container typesLimited container types
GDC Roadtrip Dec 1999
Key ConceptsKey Concepts Generic Generic algorithmsalgorithms ContainerContainer classes classes IteratorsIterators : “container walkers” for : “container walkers” for
accessing container elementsaccessing container elements Iterators provide an abstraction of Iterators provide an abstraction of
container access, which in turn container access, which in turn allows for generic algorithmsallows for generic algorithms
Iterator invalidationIterator invalidation
GDC Roadtrip Dec 1999
Key Concepts (cont.)Key Concepts (cont.) Ranges: C/C++ “past-the-end” pointerRanges: C/C++ “past-the-end” pointer
T Wallace[N];T Wallace[N];T* p = (Wallace + N); T* p = (Wallace + N); // valid pointer// valid pointerT w = *(Wallace + N); T w = *(Wallace + N); // invalid dereference// invalid dereference
c.begin() == (Wallace); c.begin() == (Wallace); // first element// first elementc.end() == (Wallace + N); c.end() == (Wallace + N); // valid iterator// valid iterator*c.end(); *c.end(); // invalid dereference// invalid dereference
end() - begin() = size()end() - begin() = size() if (begin() == end()) container is emptyif (begin() == end()) container is empty for (iter i = begin(); i != end() ++i)for (iter i = begin(); i != end() ++i)
GDC Roadtrip Dec 1999
Key Concepts (cont.)Key Concepts (cont.) Linear search exampleLinear search example
template <class InputItr, class T> InputItrtemplate <class InputItr, class T> InputItrfindfind(InputItr bg, InputItr end, const T& val)(InputItr bg, InputItr end, const T& val){ while (bg { while (bg !=!= end && end && **bg bg !=!= val) val) ++++bg;bg; return (bg); }return (bg); }
const int nSize = 4;const int nSize = 4;int Gromit[nSize] = { 5, 18, 23, 9 };int Gromit[nSize] = { 5, 18, 23, 9 };int* pFind = int* pFind = findfind(Gromit, Gromit + nSize, 23);(Gromit, Gromit + nSize, 23);
vector<int> Preston;vector<int> Preston;vector<int>::iterator i = vector<int>::iterator i = findfind(Preston.begin(), Preston.end(), 4);(Preston.begin(), Preston.end(), 4);
GDC Roadtrip Dec 1999
Putting the STL into ActionPutting the STL into Action Include files have no “.h”Include files have no “.h” Standard namespaceStandard namespace
#include <cstdio>#include <cstdio> // new include method// new include method#include <vector>#include <vector> // vector container// vector container#include <algorithm>#include <algorithm> // STL algorithms// STL algorithmsusing namespace std;using namespace std; // assume std::// assume std::
vector<int> Chuck;vector<int> Chuck; // declare a growable array// declare a growable arrayChuck.push_back(1);Chuck.push_back(1); // add an element// add an elementfind(Chuck.begin(), Chuck.end(), 1);find(Chuck.begin(), Chuck.end(), 1);
GDC Roadtrip Dec 1999
ContainersContainers Containers Containers containcontain elements; they elements; they
“own” the objects“own” the objects Containers provide iterators that Containers provide iterators that
point to its elements.point to its elements. Containers provide a minimal set Containers provide a minimal set
of operations for manipulating of operations for manipulating elementselements
GDC Roadtrip Dec 1999
Containers (cont.)Containers (cont.)Container Description Keys
vector dynamic arraydeque dynamic array -- both endslist linked listset sorted list of keys no duplicate keysmap sorted list of key and value pairs no duplicate keysmultiset sorted list of keys duplicate keys OKmultimap sorted list of key and value pairs duplicate keys OK
Minimum container object requirementsMinimum container object requirements
X() X() // default ctor// default ctorX(const X&) X(const X&) // copy ctor// copy ctorX& operator = (const X&) X& operator = (const X&) // assignment op// assignment opbool operator < (const X&) bool operator < (const X&) // comparison op// comparison opbool operator == (const X&) bool operator == (const X&) // comparison op// comparison op
GDC Roadtrip Dec 1999
VectorVector Dynamic arrayDynamic array Fast ins/erase from end of vectorFast ins/erase from end of vector reserve(), capacity()reserve(), capacity() Contiguous block of memoryContiguous block of memory Obliged to grow by some factor (2x) Obliged to grow by some factor (2x)
when size() exceeds capacity()when size() exceeds capacity() Insert invals all iters if capacity Insert invals all iters if capacity
change; insert/erase invals all iters change; insert/erase invals all iters followingfollowing
GDC Roadtrip Dec 1999
DequeDeque Double-ended queue (“deck”)Double-ended queue (“deck”) Fast ins/erase at begin Fast ins/erase at begin andand end end Directory array of pointers to nodes, Directory array of pointers to nodes,
where each node is small array of Twhere each node is small array of T Insert invals all iters; erase in Insert invals all iters; erase in
middle invals all; erase at begin/end middle invals all; erase at begin/end on invals iter to begin/endon invals iter to begin/end
GDC Roadtrip Dec 1999
ListList Doubly-linked listDoubly-linked list Fast insert/erase; no random Fast insert/erase; no random
accessaccess Special functions: splice(), merge()Special functions: splice(), merge() Erase invals iters to erased Erase invals iters to erased
elements; insert never invals any elements; insert never invals any itersiters
GDC Roadtrip Dec 1999
SetSet List of sorted elementsList of sorted elements Fast retrieval based on key (log N)Fast retrieval based on key (log N) Fast insert/erase (log N)Fast insert/erase (log N) Red-black tree (balanced 2-3-4 Red-black tree (balanced 2-3-4
tree)tree) Erase invals erased elems; insert Erase invals erased elems; insert
never invals any itersnever invals any iters
GDC Roadtrip Dec 1999
MapMap Dictionary of sorted elementsDictionary of sorted elements List of sorted key and value pairsList of sorted key and value pairs Same implementation and Same implementation and
characteristics of set containercharacteristics of set container
GDC Roadtrip Dec 1999
Container AdaptorsContainer Adaptors
Example adapator codeExample adapator code
stack<intstack<int, deque<int>, deque<int> > TechnoTrousers; > TechnoTrousers;TechnoTrousers.push(1);TechnoTrousers.push(1);int i = TechnoTrousers.top();int i = TechnoTrousers.top();TechnoTrousers.pop();TechnoTrousers.pop();
Adaptor Example containers Default container
stack list, deque, vector dequequeue list, deque dequepriority_queue list, deque, vector vector
GDC Roadtrip Dec 1999
What’s Missing?What’s Missing? stack-based arrays (T a[N])stack-based arrays (T a[N]) hash tableshash tables singly-linked listssingly-linked lists some STL implementations include some STL implementations include
one or more of these “non-one or more of these “non-standard” containersstandard” containers
GDC Roadtrip Dec 1999
Container EfficiencyContainer Efficiency
Overhead is approx. per-element size in bytesOverhead is approx. per-element size in bytes Hash and slist containers included for comparison only. Hash and slist containers included for comparison only.
C/N indicates best/worst case timesC/N indicates best/worst case times
Container Overhead Insert Erase [] Find Sortlist 8 C C n/a N N log Ndeque 12 C at begin or
end; else N/2C at begin orend; else N
C N N log N
vector 0 C at end; else N C at end; else N C N N log Nset 12 log N log N n/a log N Cmultiset 12 log N d log (N+d) n/a log N Cmap 16 log N log N log N log N Cmultimap 16 log N d log (N+d) log N log N Cstack n/a C C n/a n/a n/aqueue n/a C C n/a n/a n/apriority_queue
n/a log N log N n/a n/a n/a
slist (SGI) 4 C C n/a N n/ahashset (SGI) ? C/N C/N n/a C/N n/ahashmap(SGI)
? C/N C/N n/a C/N n/a
GDC Roadtrip Dec 1999
IteratorsIterators
Typical iterationTypical iteration
c<T>::iterator i;c<T>::iterator i;for (i = c.begin(); i != c.end() ++i) for (i = c.begin(); i != c.end() ++i) // forward// forward T t = *i;T t = *i;
for (i = c.rbegin(); i != c.rend() ++i) for (i = c.rbegin(); i != c.rend() ++i) // backward// backward T t = *i;T t = *i;
Type Valid expressions ExampleInput *t, ++i, i++, *i++ find() (read-only)Output *x = t, *x++ = t, ++x, x++ insert_iterator<C> (write-only)Forward ++i, i++, *x=t slist<T>::iterator (SGI-specific)Bidirectional ++i, i++, --i, i--, *x=t list<T>::iteratorRandom Bidrect’l, i += n, i + n, i -= n, i – n,
i[n], i[n] = tvector<T>::iterator, deque<T>::iterator
GDC Roadtrip Dec 1999
AlgorithmsAlgorithms Approx. 60 standard algorithmsApprox. 60 standard algorithms
– searching (e.g. find())searching (e.g. find())– sorting (e.g. sort())sorting (e.g. sort())– mutating (e.g. transform())mutating (e.g. transform())– numerical (e.g. accumulate())numerical (e.g. accumulate())
Most functions take the form:Most functions take the form:– fn(c.begin(), c.end(), ...)fn(c.begin(), c.end(), ...)
GDC Roadtrip Dec 1999
Algorithms (cont.)Algorithms (cont.) Examples:Examples:
#include <algorithm>#include <algorithm>
// return num elements equal to 123// return num elements equal to 123int i = int i = countcount(c.begin(), c.end(), 123);(c.begin(), c.end(), 123);
// negate all elements// negate all elementstransformtransform(c.begin(), c.end(), negate<int>());(c.begin(), c.end(), negate<int>());
// print all elements// print all elementsfor_eachfor_each(c.begin(), c.end(), print<int>());(c.begin(), c.end(), print<int>());
// shuffle the deck// shuffle the deckrandom_shufflerandom_shuffle(deck.begin(), deck.end());(deck.begin(), deck.end());
GDC Roadtrip Dec 1999
Function Objects Function Objects (Functors)(Functors)
C++ objects that can be called like C++ objects that can be called like a function to implement a function to implement “callbacks”“callbacks”
Use C++ operator()(...)Use C++ operator()(...) Simplest type is a function pointerSimplest type is a function pointer
bool bool StlStrCompStlStrComp(const char* a, const char* b)(const char* a, const char* b) { return (strcmp(a, b) == -1); }{ return (strcmp(a, b) == -1); }
vector<char*> v;vector<char*> v;sort(v.begin(), v.end(), sort(v.begin(), v.end(), StlStrCompStlStrComp););
GDC Roadtrip Dec 1999
Functors (cont.)Functors (cont.) Functors that do ordering are Functors that do ordering are
called “predicates”called “predicates”
struct struct StlStrPred StlStrPred // “public” class// “public” class{ bool operator()(const char* a, const char* b){ bool operator()(const char* a, const char* b) { return (strcmp(a, b) == -1); } };{ return (strcmp(a, b) == -1); } };
vector<char*> v;vector<char*> v;sort(v.begin(), v.end(), sort(v.begin(), v.end(), StlStrPred()StlStrPred()););
GDC Roadtrip Dec 1999
EfficiencyEfficiency Designed to be as fast as hand-Designed to be as fast as hand-
coded routinescoded routines Limiting factor is typically copy Limiting factor is typically copy
ctor and assignment operatorctor and assignment operator
GDC Roadtrip Dec 1999
Efficiency (cont.)Efficiency (cont.) STL STL fasterfaster in some cases than in some cases than
standard C functionsstandard C functions
const char* WestWallaby = “Gromit”;const char* WestWallaby = “Gromit”;strchrstrchr(WestWallaby, ‘m’);(WestWallaby, ‘m’);findfind(WestWallaby, WestWallaby+6, ‘m’);(WestWallaby, WestWallaby+6, ‘m’);
GDC Roadtrip Dec 1999
Efficiency (cont.)Efficiency (cont.) Sorting (ints)Sorting (ints)
int arr[nElements];
qsort(arr, nElements, sizeof(int), IntComp);
int arr[nElements];
sort(arr, arr + nElements); // STL int array sort
vector<int> v;
sort(v.begin(), v.end()); // STL int vector sort
GDC Roadtrip Dec 1999
Efficiency (cont.)Efficiency (cont.) Sorting (strings)Sorting (strings)
char* arr[nElements];
qsort(arr, nElements, sizeof(char*), StrComp);
sort(arr, arr + nElements, StlStrComp);
sort(v.begin(), v.end(), StlStrComp); // char*
sort(v.begin(), v.end(), StlStrComp); // string
GDC Roadtrip Dec 1999
STL AllocatorsSTL Allocators Every STL container takes an Every STL container takes an
allocator object as a template allocator object as a template parameterparametertemplate <class T> public AllocSpecialCheesetemplate <class T> public AllocSpecialCheese{ public:{ public: pointer allocate(size_type, const void*);pointer allocate(size_type, const void*); void deallocate(void*, size_type); void deallocate(void*, size_type); // ... other boilerplate code here// ... other boilerplate code here};};
set<int> Camembert; set<int> Camembert; // default allocator// default allocator
// All Wensleydale allocations use special allocator// All Wensleydale allocations use special allocatorset<int, AllocSpecialCheese> Wensleydale;set<int, AllocSpecialCheese> Wensleydale;
GDC Roadtrip Dec 1999
Template Partial Template Partial SpecializationSpecialization
// generic template function for swapping objects// generic template function for swapping objectstemplate <class T> void swap(T& x, T& y)template <class T> void swap(T& x, T& y) { T z(x); x = y; y = z; }{ T z(x); x = y; y = z; }
swap(v1, v2); swap(v1, v2); // swapping vectors: slow!// swapping vectors: slow!v1.swap(v2); v1.swap(v2); // swapping vectors: fast!// swapping vectors: fast!
// template partial specialization// template partial specializationtemplate <class T> void swap(template <class T> void swap(vector<T>vector<T>& x,& x, vector<T>vector<T>& y)& y) { x.swap(y); }{ x.swap(y); }
swap(v1, v2); swap(v1, v2); // fast!// fast!
GDC Roadtrip Dec 1999
Template Specialization part Template Specialization part II II
// STL generic copy() algorithm
template<class InItr, class OutItr> OutItr
copy(InItr bg, InItr end, OutItr val)
{ for (; bg != end; ++val, ++bg)
*val = *bg;
return (val); }
// A fast version for simple memory chunks
template<> char* copy(const char* bg,
const char* end, char* val)
{ size_t n = end - bg;
memcpy(val, bg, n);
return (val + n); }
GDC Roadtrip Dec 1999
Thread SafetyThread Safety Official answer: STL has no thread Official answer: STL has no thread
safety obligations whatsoeversafety obligations whatsoever One (bad) answer: have STL handle One (bad) answer: have STL handle
all synchronization issuesall synchronization issues Typical answer: make STL thread Typical answer: make STL thread
safe internally, but require users to safe internally, but require users to insure no thread accesses a insure no thread accesses a container when another thread container when another thread modifies the containermodifies the container
GDC Roadtrip Dec 1999
Thread Safety (cont.)Thread Safety (cont.) Current status of implementationsCurrent status of implementations
– Original HP version Original HP version notnot thread safe thread safe– SGI thread safeSGI thread safe– VC VC mostlymostly thread safe thread safe (dinkumware.com/vc_fixes.html)(dinkumware.com/vc_fixes.html)
Typical STL implementation promisesTypical STL implementation promises– Multiple reads is thread safeMultiple reads is thread safe– Read/write across different containers, same Read/write across different containers, same
objects, is thread safeobjects, is thread safe– Writes to a container by one thread and Writes to a container by one thread and
read/writes by another thread is read/writes by another thread is notnot thread safe; thread safe; users must preventusers must prevent
GDC Roadtrip Dec 1999
Exception SafetyException Safety C++ standard requires the followingC++ standard requires the following
– destructors may not throw excptnsdestructors may not throw excptns– valid iterator operations may not throwvalid iterator operations may not throw– containers must “survive” excptns; containers must “survive” excptns;
content unspecified, but still destructablecontent unspecified, but still destructable– an excptn thrown while inserting one an excptn thrown while inserting one
element leaves the container unchangedelement leaves the container unchanged– an excptn thrown while inserting two+ an excptn thrown while inserting two+
elements leaves a elements leaves a listlist unchanged unchanged
GDC Roadtrip Dec 1999
Code BloatCode Bloat Templates expand into different Templates expand into different
sets of code for each type Tsets of code for each type T If different types have the same If different types have the same
size and same comparison size and same comparison functions, the compiler can functions, the compiler can optimizeoptimize
Some STL implementations are Some STL implementations are optimized to minimize code bloat optimized to minimize code bloat (XTL from DeltaLogic)(XTL from DeltaLogic)
GDC Roadtrip Dec 1999
Compiler Warnings & Compiler Warnings & ErrorsErrors
VC warning C4786: identifier VC warning C4786: identifier truncationtruncation
#pragma warning(disable: 4786) #pragma warning(disable: 4786) // before headers!// before headers!
Errors/warnings in header filesErrors/warnings in header files– really means: your code has a problemreally means: your code has a problem
Interpreting gonzo error messagesInterpreting gonzo error messages
map<string, int> m;map<string, int> m;
map<string, int>const_iterator i = m.find(“abc”);map<string, int>const_iterator i = m.find(“abc”);
m.erase(i); m.erase(i); // “big” error here// “big” error here
GDC Roadtrip Dec 1999
Compiler Errors (cont.)Compiler Errors (cont.)error C2664: 'class std::_Tree<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char>
>,struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int>,struct std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<int> >::_Kfn,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<int> >::iterator __thiscall std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,struct std::less<class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > >,class std::allocator<int> >::erase(class std::_Tree<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int>,struct std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<int> >::_Kfn,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
>,class std::allocator<int> >::iterator)' : cannot convert parameter 1 from 'class std::_Tree<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int>,struct std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<int> >::_Kfn,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > >,class std::allocator<int> >::const_iterator' to 'class std::_Tree<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int>,struct std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<int> >::_Kfn,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
>,class std::allocator<int> >::iterator'
No constructor could take the source type, or constructor overload resolution was ambiguous
GDC Roadtrip Dec 1999
Extending the STLExtending the STL Designed for extensionDesigned for extension Not difficult to write new Not difficult to write new
algorithms, containers, or iteratorsalgorithms, containers, or iterators SGI implementation has many SGI implementation has many
useful container extensions (hash useful container extensions (hash tables, slist)tables, slist)
GDC Roadtrip Dec 1999
Our own AlgorithmOur own Algorithm// Compute sum of all squares in range
template<class InItr, class T> T
sumsqrs(InItr bg, InItr end, T init)
{ T ss(init);
for (; bg != end; ++bg) { ss += (*bg) * (*bg); }
return (ss); }
int CloseShave[4] = { 1, 2, 3, 4 };
int x = sumsqrs(CloseShave, CloseShave+4, 0); // 30
deque<double> WrongTrousers; // 1.1, 2.2, 3.3
double y = sumsqrs(WrongTrousers.begin(), // 16.94
WrongTrousers.end(), 0.0);
GDC Roadtrip Dec 1999
Our own IteratorOur own Iteratortemplate <class C, class T, class A = allocator<T> >
struct MfcIt : public _Ranit<T, A::difference_type> {
C* mpC; // MFC container
int mI; // index into container
MfcIt(C* pC = 0) : mpC(pC), mI(0) {}
MfcIt(C* pC, int n) : mpC(pC), mI(n) {}
MfcIt begin() { return (MfcIt(mpC, 0)); }
MfcIt end() { return (MfcIt(mpC, mpC->GetSize())); }
T& operator * () const { return ((*mpC)[mI]); }
MfcIt& operator ++ () { if (mI < mpC->GetSize()) ++mI; else mI = 0;
return (*this); }
MfcIt operator + (difference_type n) const { MfcIt tmp = *this;
return (tmp += n); }
bool operator == (const MfcIt& i) const { return ((mI == i.mI) &&
(mpC == i.mpC)); }
bool operator < (const MfcIt& i) const { return ((mI < i.mI) && (mpC == i.mpC)); }
};
GDC Roadtrip Dec 1999
Our own Iterator (cont.)Our own Iterator (cont.) Example of using the MFC/STL Example of using the MFC/STL
iteratoriterator
// MFC container
CStringArray arr;
arr.Add("xyz");
arr.Add("abc");
// Create STL iterator from MFC container
MfcIt<CStringArray, CString> mfc(&arr);
// Sort the MFC container using an STL algorithm!
sort(mfc.begin(), mfc.end());
GDC Roadtrip Dec 1999
Common MistakesCommon Mistakes Template of templatesTemplate of templates
stack<vector<int>> GoneWrong; // need space: “> >”
Same algorithm, different containerSame algorithm, different container
sort(Marmalade.begin(), Jelly.end()) // crash!
Right iterator, wrong containerRight iterator, wrong container
list<int>::iterator i = Feathers.begin();
McGraw.erase(i); // i doesn’t point into McGraw!
GDC Roadtrip Dec 1999
Common Mistakes (cont.)Common Mistakes (cont.) Invalid iteratorInvalid iterator
vector<int>::iterator i = GrandDayOut.begin();
GrandDayOut.push_back(1); // potential realloc
TheCooker(*i); // uh-oh! i might be invalid
Adding elements with subscript opAdding elements with subscript op
vector<char> Wendolene;
Wendolene[0] = ‘W’; // crash!
Wendolene.push_back(‘W’); // the right way
GDC Roadtrip Dec 1999
Common Mistakes (cont.)Common Mistakes (cont.) Sorting problemsSorting problems
– e.g. lookups fail, a set gets duplicatese.g. lookups fail, a set gets duplicates Usually a problem with op < or op ==Usually a problem with op < or op == RulesRules
– if x<y is true, y>x is always falseif x<y is true, y>x is always false– if x<y && y<z are true, x<z is always if x<y && y<z are true, x<z is always
falsefalse– if x==y, then x<y is always falseif x==y, then x<y is always false– if !(x<y) and !(y<x), x == yif !(x<y) and !(y<x), x == y
GDC Roadtrip Dec 1999
Hiding the Angle BracketsHiding the Angle Brackets Not prettyNot pretty
// This is hard to read
map<string, int> Shaun;
Shaun.insert(pair<string, int>(“abc”, 31));
map<string, int>::iterator i = Shaun.find(“abc”);
pair<string, int> pr = *i;
pr.first; // “abc”
pr.second; // int
GDC Roadtrip Dec 1999
Hiding the Angle Brackets Hiding the Angle Brackets (cont.)(cont.)
Typedefs are your friendTypedefs are your friend
// Tuck these away in a header file
typedef map<string, int> ShaunMap;
typedef pair<string, int> ShaunPair;
typedef ShaunMap::iterator ShaunItr;
// Same code, but no more angle brackets
ShaunMap Shaun;
Shaun.insert(ShaunPair(“abc”, 31));
ShaunItr i = Shaun.find(“abc”);
ShaunPair pr = *i;
GDC Roadtrip Dec 1999
Storing Pointers in Storing Pointers in ContainersContainers
Container will Container will notnot delete the pointers delete the pointers when the container goes awaywhen the container goes away
Will sort on pointer, not what it Will sort on pointer, not what it contains, unless you tell it otherwisecontains, unless you tell it otherwise
deque<int*> Walkies; // sorted by pointer
sort(Walkies.begin(), Walkies.end());
bool intpLess(const int* a, const int* j)
{ return (*a < *b); } // sorted by int
sort(Walkies.begin(), Walkies.end(), intpLess);
GDC Roadtrip Dec 1999
Vector TipsVector Tips Use reserve() to set aside space Use reserve() to set aside space
when vector size is known in advancewhen vector size is known in advance Can I safely take the address of a Can I safely take the address of a
vector element, e.g. &v[21]?vector element, e.g. &v[21]?– According to Standard, no. According to According to Standard, no. According to
practice, yes. Standard expected to practice, yes. Standard expected to adjust.adjust.
Trimming unused spaceTrimming unused space
v.swap(vector<T>(v)); // vector, swap thyself!
GDC Roadtrip Dec 1999
Copying ContainersCopying Containers The wrong way; copy() can’t add The wrong way; copy() can’t add
elemselems
copy(v.begin(), v.end(), nv.begin()); // uh-oh
Better and bestBetter and best
nv.resize(v.size()); // size of nv matches v
copy(v.begin(), v.end(), nv.begin());
copy(v.begin(), v.end(), back_inserter(nv));
copy(m.begin(), m.end(), insert_iterator<T>
/* map and set use this method */ (nm, nm.begin());
GDC Roadtrip Dec 1999
Algorithms that Remove Algorithms that Remove ElemsElems
Algorithms by themselves can’t Algorithms by themselves can’t insert or delete elements, so they insert or delete elements, so they move them!move them!
unique() moves unique elems to the unique() moves unique elems to the front and returns an iter to the new front and returns an iter to the new “end” of the container“end” of the container
remove() similarly moves the remove() similarly moves the “unremoved” elems to the front and “unremoved” elems to the front and returns an iter to the new “end”returns an iter to the new “end”
GDC Roadtrip Dec 1999
Removing Elems (cont.)Removing Elems (cont.) To actually get rid of the extra To actually get rid of the extra
elems, you must call erase()elems, you must call erase()
// Removes duplicates and shrinks the container
v.erase(unique(v.begin(), v.end()), v.end());
// Removes the given elements and shrinks v
v.erase(remove(v.begin(), v.end(), 1), v.end());
GDC Roadtrip Dec 1999
Vectors vs C-style arraysVectors vs C-style arrays Prefer vector or deque over arraysPrefer vector or deque over arrays Don’t have to know size in Don’t have to know size in
advanceadvance Don’t have to keep track of size Don’t have to keep track of size
separatelyseparately Little loss of efficiencyLittle loss of efficiency Vector works well with legacy code Vector works well with legacy code
that expect arraysthat expect arrays
GDC Roadtrip Dec 1999
Deque vs VectorDeque vs Vector Almost identical usability Almost identical usability
characteristicscharacteristics Faster middle insertion because Faster middle insertion because
deque only needs to shift a chunkdeque only needs to shift a chunk Constant-time insertion at the frontConstant-time insertion at the front Uses memory in a more operating Uses memory in a more operating
system-friendly waysystem-friendly way Don’t need to worry about reserve()Don’t need to worry about reserve()
GDC Roadtrip Dec 1999
The “Key” RequirementThe “Key” Requirement Once a key has been inserted into Once a key has been inserted into
a container, the key should not a container, the key should not changechange
Can’t be enforced internally by the Can’t be enforced internally by the STLSTL
Example: key is a filename; Example: key is a filename; comparison is based on file comparison is based on file contentscontents
GDC Roadtrip Dec 1999
Copy() vs Memcpy()Copy() vs Memcpy() copy() works reliably with copy() works reliably with allall objects objects memcpy() unsafe on any object with a memcpy() unsafe on any object with a
copy ctorcopy ctor copy() can copy a sequence whose copy() can copy a sequence whose
length is not known in advancelength is not known in advance copy() returns an iter to the end of the copy() returns an iter to the end of the
copy; can be used as concatenation copy; can be used as concatenation tooltool
good implementation will optimizegood implementation will optimize
GDC Roadtrip Dec 1999
Wrap UpWrap Up Algorithms, Containers, IteratorsAlgorithms, Containers, Iterators Efficient, Flexible, ExtensibleEfficient, Flexible, Extensible Angle Brackets... mmmAngle Brackets... mmm
GDC Roadtrip Dec 1999
ReferencesReferences Email me: [email protected] me: [email protected] Home page: www.tantalon.comHome page: www.tantalon.com Books: Generic Programming & the Books: Generic Programming & the
STL (Austern), STL Tutorial & STL (Austern), STL Tutorial & Reference Guid (Musser)Reference Guid (Musser)
Websites: sgi.com/Technology/STL, Websites: sgi.com/Technology/STL, dinkumware.com, deltalogic.com, dinkumware.com, deltalogic.com, roguewave.com, stlport.orgroguewave.com, stlport.org