+ All Categories
Home > Documents > Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

Date post: 06-Feb-2016
Category:
Upload: rane
View: 36 times
Download: 0 times
Share this document with a friend
Description:
Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee. Introduction. STL Background & History Key Concepts Containers, Iterators and Algorithms Efficiency and Thread Safety Tips and Tricks. Goals. STL Newbie Convince you that it’s a “good thing” - PowerPoint PPT Presentation
59
GDC Roadtrip Dec 1999 Embracing the C++ STL: Embracing the C++ STL: Why Angle Brackets are Why Angle Brackets are Good for You Good for You Pete Isensee Pete Isensee
Transcript
Page 1: 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 YouPete IsenseePete Isensee

Page 2: Embracing the C++ STL: Why Angle Brackets are Good for You Pete 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

Page 3: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 4: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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!

Page 5: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

HistoryHistory Alex Stepanov & Meng Lee, based on Alex Stepanov & Meng Lee, based on

earlier work by Stepanov & Musserearlier work by Stepanov & Musser 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

Page 6: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 7: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 8: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 9: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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)

Page 10: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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);

Page 11: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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);

Page 12: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 13: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

Containers (cont.)Containers (cont.)Container Description Keysvector 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 requirementsX() 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

Page 14: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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 change; Insert invals all iters if capacity change;

insert/erase invals all iters followinginsert/erase invals all iters following

Page 15: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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 middle Insert invals all iters; erase in middle

invals all; erase at begin/end on invals all; erase at begin/end on invals iter to begin/endinvals iter to begin/end

Page 16: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 17: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 18: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 19: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

Container AdaptorsContainer Adaptors

Example adapator codeExample adapator codestack<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 containerstack list, deque, vector dequequeue list, deque dequepriority_queue list, deque, vector vector

Page 20: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 21: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 22: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

IteratorsIterators

Typical iterationTypical iterationc<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

Page 23: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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(), ...)

Page 24: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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());

Page 25: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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););

Page 26: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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()););

Page 27: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 28: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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’);

Page 29: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 30: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 31: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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;

Page 32: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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!

Page 33: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

Template Specialization part Template Specialization part II II

// STL generic copy() algorithmtemplate<class InItr, class OutItr> OutItrcopy(InItr bg, InItr end, OutItr val){ for (; bg != end; ++val, ++bg) *val = *bg; return (val); }

// A fast version for simple memory chunkstemplate<> char* copy(const char* bg, const char* end, char* val){ size_t n = end - bg; memcpy(val, bg, n); return (val + n); }

Page 34: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 35: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 36: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 37: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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 size If different types have the same size

and same comparison functions, the and same comparison functions, the compiler can optimizecompiler can optimize

Some STL implementations are Some STL implementations are optimized to minimize code bloat optimized to minimize code bloat (XTL from DeltaLogic)(XTL from DeltaLogic)

Page 38: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

Compiler Warnings & Compiler Warnings & ErrorsErrors

VC warning C4786: identifier truncationVC warning C4786: identifier truncation#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 messagesmap<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

Page 39: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 40: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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)

Page 41: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

Our own AlgorithmOur own Algorithm// Compute sum of all squares in rangetemplate<class InItr, class T> Tsumsqrs(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.3double y = sumsqrs(WrongTrousers.begin(), // 16.94 WrongTrousers.end(), 0.0);

Page 42: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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)); }};

Page 43: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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 containerCStringArray arr;arr.Add("xyz");arr.Add("abc");

// Create STL iterator from MFC containerMfcIt<CStringArray, CString> mfc(&arr);

// Sort the MFC container using an STL algorithm!sort(mfc.begin(), mfc.end());

Page 44: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

Common MistakesCommon Mistakes Template of templatesTemplate of templates

stack<vector<int>> GoneWrong; // need space: “> >”

Same algorithm, different containerSame algorithm, different containersort(Marmalade.begin(), Jelly.end()) // crash!

Right iterator, wrong containerRight iterator, wrong containerlist<int>::iterator i = Feathers.begin();McGraw.erase(i); // i doesn’t point into McGraw!

Page 45: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

Common Mistakes (cont.)Common Mistakes (cont.) Invalid iteratorInvalid iterator

vector<int>::iterator i = GrandDayOut.begin();GrandDayOut.push_back(1); // potential reallocTheCooker(*i); // uh-oh! i might be invalid

Adding elements with subscript opAdding elements with subscript opvector<char> Wendolene;Wendolene[0] = ‘W’; // crash!Wendolene.push_back(‘W’); // the right way

Page 46: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 47: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

Hiding the Angle BracketsHiding the Angle Brackets Not prettyNot pretty

// This is hard to readmap<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

Page 48: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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 filetypedef map<string, int> ShaunMap;typedef pair<string, int> ShaunPair;typedef ShaunMap::iterator ShaunItr;

// Same code, but no more angle bracketsShaunMap Shaun;Shaun.insert(ShaunPair(“abc”, 31));ShaunItr i = Shaun.find(“abc”);ShaunPair pr = *i;

Page 49: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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 otherwisedeque<int*> Walkies; // sorted by pointersort(Walkies.begin(), Walkies.end());

bool intpLess(const int* a, const int* j) { return (*a < *b); } // sorted by intsort(Walkies.begin(), Walkies.end(), intpLess);

Page 50: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

Vector TipsVector Tips Use reserve() to set aside space when Use reserve() to set aside space when

vector size is known in advancevector 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 spacev.swap(vector<T>(v)); // vector, swap thyself!

Page 51: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

Copying ContainersCopying Containers The wrong way; copy() can’t add The wrong way; copy() can’t add

elemselemscopy(v.begin(), v.end(), nv.begin()); // uh-oh

Better and bestBetter and bestnv.resize(v.size()); // size of nv matches vcopy(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());

Page 52: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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”

Page 53: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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 containerv.erase(unique(v.begin(), v.end()), v.end());

// Removes the given elements and shrinks vv.erase(remove(v.begin(), v.end(), 1), v.end());

Page 54: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 55: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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()

Page 56: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 57: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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

Page 58: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

GDC Roadtrip Dec 1999

Wrap UpWrap Up Algorithms, Containers, IteratorsAlgorithms, Containers, Iterators Efficient, Flexible, ExtensibleEfficient, Flexible, Extensible Angle Brackets... mmmAngle Brackets... mmm

Page 59: Embracing the C++ STL: Why Angle Brackets are Good for You Pete Isensee

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


Recommended