41
C++ Standard Template Library Ausgew ¨ ahlte Kapitel aus Softwaretechnologie Robert Fritz [email protected] C++ Standard Template Library (STL) – p.1/41

Ausgew¨ahlte Kapitel aus Softwaretechnologie · Einf¨uhrung • Sch¨opfer der STL: Alex Stepanov und Meng Lee (Forschungsprojekt ¨uber generische Algorithmen. Vorschl ¨age wurden

Embed Size (px)

Citation preview

C++ Standard Template LibraryAusgewahlte Kapitel aus Softwaretechnologie

Robert Fritz

[email protected]

C++ Standard Template Library (STL) – p.1/41

Inhalt

• Einfuhrung• Generisches Programmieren

• Aufbau der C++ Standard Template Library• Container (Template Klassen)

• Sequenzen (vector, list, ...)• Adaptierte Sequenzen (stack, queue, ...)• Assoziative Container (set, map, ...)

• Iteratoren• Algorithmen (Template Funktionen)

C++ Standard Template Library (STL) – p.2/41

Einfuhrung

• Schopfer der STL: Alex Stepanov und Meng Lee(Forschungsprojekt uber generische Algorithmen. Vorschlagewurden weitesgehend vom ANSI-Komitee ubernommenwurden)

• Verallgemeinerung von Datenstrukturen und Algorithmen

• C++ Templates: allgemeines Template<T>, T ist einverallgemeinerter Parameter Typ

• Bei der Instantiierung wird der allgemeine Typ durch speziellenTyp ersetzt - Objekte, Pointer, Standardtypen (int, char, ...)

• Anderungen leicht moglich

• Algorithmen sind globale Funktionen (OOP?)• C++ stellt zwei Arten von Templates zur Verfugung:

• Template Klassen - Container (Listen, Sets, Vektoren, ...)

• Template Funktionen - Algorithmen (Sortier -und Suchfunktionen, ...)

C++ Standard Template Library (STL) – p.3/41

Generisches Programmieren

• Algorithmen werden mit minimalem Wissen uber die

Datenabstraktion geschrieben und vice versa.

• Verallgemeinerung von Algorithmen ohne die Effizient zu

verlieren.

• Gleiche Effizienz von spezialisiertem Algorithmus und

originalem Algorithmus.

• Verschiedene Verallgemeinerungsstufen (automatische

Auswahl des effizientesten Algorithmus)

• Mehrere Algorithmen fur den selben Zweck auf dem selben

Abstraktionslevel.

C++ Standard Template Library (STL) – p.4/41

Verwendung von Template Klassen 1/2

Deklaration und Definition der Template Klassen mussen in einerHeader Datei erfolgen.template <class T>

class Stack

{

public:

Stack(int = 10) ;

~Stack() { delete [] stackPtr ; }

int push(const T&);

int pop(T&) ;

int isEmpty()const { return top == -1 ; }

int isFull() const { return top == size - 1 ; }

private:

int size ; // number of elements on Stack.

int top ;

T* stackPtr ;

};

C++ Standard Template Library (STL) – p.5/41

Verwendung von Template Klassen 2/2

#include <iostream>

#include "stack.h"

using namespace std ;

void main()

{

typedef Stack<float> FloatStack ;

typedef Stack<int> IntStack ;

FloatStack fs(5) ;

float f = 1.1 ;

cout << "Pushing elements onto fs" << endl ;

while (fs.push(f))

{

cout << f << ’ ’ ;

f += 1.1 ;

}

cout << endl << "Stack Full." << endl

// ...

}

C++ Standard Template Library (STL) – p.6/41

Verwendung von Template Funktionen

template <class T>

T max(T a, T b)

{

return a > b ? a : b ;

}

void main()

{

cout << "max(10, 15) = " << max(10, 15) << endl ;

cout << "max(’k’, ’s’) = " << max(’k’, ’s’) << endl ;

cout << "max(10.1, 15.2) = " << max(10.1, 15.2) << endl ;

}

C++ Standard Template Library (STL) – p.7/41

C++ Standard Template Library

• Grundproblem:• n verschiedene Datentypen (int, double, void *, ...)• m verschiedene Container (vector<>, list<>, ...)• k Algorithmen (sort, unique, ...)• Herkommliche Programmierung: n*m*k verschiedene

Implementierungen

• Templates erlauben, die Algorithmen fur beliebige Typen zuimplementieren.

• Voraussetzung ist, dass alle Container eine gewisseMinimalschnittstelle unterstutzen.

• Diese Minimalanforderungen an die Container sind inverschiedene Gruppen gegliedert.

• Nicht alle Algorithmen arbeiten mit allen Container zusammen.

C++ Standard Template Library (STL) – p.8/41

C++ Standard Template Library

• Die Standard Template Library ist Bestandteil der C++Standardbibliothek.

• Alle Container und Algorithmen sind im Standard Namespacedefiniert.• using namspace std;

• oder std::vector<int> vec;

C++ Standard Template Library (STL) – p.9/41

Allgemeine Ziele der STL

Generisch Keine Festlegung auf konkrete Typen

Effizient Nicht langsamer als handgeschriebener Code

Vollstandig Behandelte Aspekte werden vollstandig

abgedeckt

Primitiv Keine Bundelung unterschiedlicher Aspekte

Typsicher Erhalt der statischen Typisierung

Erweiterbar Applikationsspezifische Spezialisierung mit

vertretbarem Aufwand

C++ Standard Template Library (STL) – p.10/41

STL: Beziehungen zwischen den Konzepten

C++ Standard Template Library (STL) – p.11/41

STL Iteratoren

• Iteratoren sind fundamental, um Container und Algorithmenverwenden zu konnen

• Traversierung von Containern nur mit Iteratoren moglich

• Jeder Container stellt je nach Datenstruktur die geeignetenIteratoren bereit• Vorwartsiteratoren, Bidirektionale Iteratoren, ...

• Iterator: Verallgemeinerung eines Pointers *iter; ...

• Iteratoren halten bestimmte Werte• Ein Paar von Iteratoren kann einen Bereich von Werten

abdecken begin(); end();

• Pointerarithmetik ist ubertragbar auf Iteratoren iter++,

iter += 5

• v.end kann nicht dereferenziert werden, enthalt keinElement

C++ Standard Template Library (STL) – p.12/41

STL Iteratoren: Verallgemeinerung

Pointer:int* find(int* array, int n, int x) {

int* p = array;

for (int i = 0; i < n; i++) {

if (*p == x)

return p; // gefunden

p++;

}

return 0; // nicht gefunden

}

Iterator:template<typename T, typename P>

P find(P first, P past_end, T x) {

while (first != past_end && *first != x)

first++;

return first; // Ergebnis

}

C++ Standard Template Library (STL) – p.13/41

STL Iteratoren: Input Iterator

• Nur lesender Zugriff: x = *iter;

• Nachstes Element: iter++; ++iter;

• Vergleichen: iter1 == iter2; iter1 != iter2

• Erzeugen: Copy-Konstruktor, Assignment-Operator

Beispiel:template <class InputIterator, class T>

InputIterator

find (InputIterator first, InputIterator last,

const T& value)

{

while (first != last && *first != value)

++first;

return first;

}

C++ Standard Template Library (STL) – p.14/41

STL Iteratoren: Output Iterator

• Nur schreibender Zurgriff: *iter = x

• Vergleichsoperator ist nicht implementiert

• Lesender Zugriff ist nicht moglich

Beispiel:template <class InputIterator, class OutputIterator>

OutputIterator copy

(InputIterator first, InputIterator last, OutputIterator result)

{

while (first != last)

*result++ = *first++;

return result;

}

C++ Standard Template Library (STL) – p.15/41

STL Iteratoren: Kategorien

Vorwarts Iterator:

• Verschmelzung von Input und Output Iterator

• Lesender Zugriff: x = *iter;

• Schreibender Zugriff: *iter = x;

Bidirektionaler Iterator:

• Wie Vorwarts Iterator

• Nachstes Element vorwarts: iter++; ++iter;

• Nachstes Element ruckwarts: iter−−; −−iter;

C++ Standard Template Library (STL) – p.16/41

STL Iteratoren: Kategorien

Random Access Iterator (vector, deque):

• Wie bidirektionaler Iterator

• Wahlfreier Zugriff: iter[];

• Nachstes Element:iter += n; iter -= n;

• Vergleiche:iter1 < iter2, ...

C++ Standard Template Library (STL) – p.17/41

STL Iteratoren: Beispielimplementierung

template <class Container>

class back_insert_iterator {

protected:

Container* container;

public:

typedef Container container_type;

typedef void value_type;

explicit back_insert_iterator(Container& x) : container(&x) {}

back_insert_iterator<Container>&

operator=(const typename Container::value_type& value) {

container->push_back(value);

return *this;

}

back_insert_iterator<Container>& operator*() { return *this; }

back_insert_iterator<Container>& operator++();

// ...

};

C++ Standard Template Library (STL) – p.18/41

STL Funktionen

Bestimmte Algorithmen akzeptieren Funktionen als Argumente.Beispiel std::for_each():void printElement(int value)

{

std::cout << "The list contains " << value << std::endl;

}

int main()

{

std::list<int> aList;

...

std::for_each(aList.begin(), aList.end(), printElement);

}

C++ Standard Template Library (STL) – p.19/41

STL Function Objects

• operator()() ist als Member Funktion implementiert

• Wird ein Function Object benutzt wird der function call

operator aufgerufen

Beispiel std::find_if():class biggerThan

{

public:

const int testValue;

biggerThan(int x) : testValue(x) { }

bool operator()(int val) const

{ return val > testValue; }

};

list<int>::iterator firstBig =

find_if(aList.begin(), aList.end(), biggerThan(12));

C++ Standard Template Library (STL) – p.20/41

STL Container

• STL bietet Container-Datenstrukturen an

• Container konnen verschiedener Typen halten:• fundamentale Typen (int, char, ...)• Pointer• benutzerdefinierte Datentypen• Container konnen keine Referenzen halten

• Schnittstellen weitestgehend vereinheitlicht

• Es werden folgende Datenstrukturen angeboten• Sequenzen (vector, deque, list, slist, bit vector)• Adaptierte Sequenzen (stack, queue, priority queue)• Assoziative Container (set, map, multiset, multimap)

C++ Standard Template Library (STL) – p.21/41

Sequence Container

• Elemente sind strikt linear angeordnet

• Unterstutzten Einfugen und Loschen von Elementen

• Typen:• Front Insertion Sequence• Back Insertion Sequence• Front und Back Insertion Sequence

C++ Standard Template Library (STL) – p.22/41

Assoziative Container

• Unterstutzten effizientes Auffinden von Elementen uber Keys

• Unterstutzten Einfugen und Loschen von Elementen

• Elemente konnen nicht an einer bestimmten Position eingefugtwerden

• Key ist entweder das Element selbst (set) oder ein einspezieller Wert des eingefugten Elements

• Keys durfen nicht verandert werden

Typen:

• Simple Associative Container

• Pair Associative Container

• Sorted Associative Container

• Unique Associative Container

• Multiple Associative Container

• ...C++ Standard Template Library (STL) – p.23/41

STL Container: vector

• Sequentieller Container

• Verallgemeinerung eines gewohnlichen C Arrays

• Indizierte Datenstruktur, Zugriff mittels operator[] moglich

• Unterschiede zu normalen Arrays:• Große des Vektors andert sich dynamisch• Neue Elemente konnen uberall eingefugt werden (effektiv

jedoch nur am Ende, im schlimmsten Fall mussen alleElemente verschoben werden - vergleiche deque)

• Ein Vektor weiß mehr uber sich als ein normales Array:• Große• potentielle Große• Wieviele Elemente er aufnehmen kann ohne neuen

Speicher allokieren zu mussen• Einfugen in einen Vektor ist

C++ Standard Template Library (STL) – p.24/41

STL Container: vector Operationen

• Copy Konstruktor muss definiert sein

• Generische Algorithmen verwenden Operatoren:operator==(), operator<(), operator=()

• Initialisierung• vector<int> vec_one(10,0);

• Initialisierung durch Zuweisung:• vector<int> vec_two(vec_two);

• Initialisierung durch Elemente aus anderen Containern• vector<int> vec(aList.begin(), aList.end());

• Zuweisung durch assign()

• vec.assign(aList.begin(), aList.end());

• vec.assign(3, 7);

• ...

C++ Standard Template Library (STL) – p.25/41

STL Container: vector Typen

Type Definition

value type The type of the elements maintained by the vector.

const iterator An iterator that does not allow modification of the underlying

sequence.

reverse iterator An iterator that moves in a backward direction.

const reverse iterator A combination constant and reverse iterator.

reference A reference to an underlying element.

const reference A reference to an underlying element that will not permit the

element to be modified.

pointer A pointer to an underlying element.

const pointer A constant pointer to an underlying element.

size type An unsigned integer type, used to refer to the size of contai-

ners.

difference type A signed integer type, used to describe distances between

iterators.

allocator type The type of allocator used to manage memory for the vector.

C++ Standard Template Library (STL) – p.26/41

STL Container: vector Member Funktionen 1/2

• Indizieren eines Vektors• vec[1] = 17;

• cout << vec[1] << endl;

• Großenabfragen• size() - Anzahl der Elemente• capacity() - reservierter Speicher• max_size() - maximale Große• empty() - effizienter als size() zu 0 zu vergleichen

• Großenanderungen• vec.reserve(20);

• vec.resize(12, 0);

C++ Standard Template Library (STL) – p.27/41

STL Container: vector Member Funktionen 2/2

Einfugen und Loschen von Elementen:

• Einfugen kann in schlechtesten Fall O(n) Zeit benotigen

• vec.push_back(21) - sehr effizient, wenn genugend Speicherreserviert ist

• vec.pop_back()

• insert:vector<int>::iterator pos = find(v.begin(),

v.end(), 7);

// then insert the 12 before the 7

v.insert(pos, 12);

v.insert(pos, 6, 14); // insert six copies of 14

• erase:v.erase(where);

v.erase(where, v.end());

C++ Standard Template Library (STL) – p.28/41

Weitere Sequenzen

list:• Bidirektionale Iteratoren

• Doppelt verlinkt

• Liste ist nicht unbedingt geordnet

• Auf Elemente kann nicht uber einen Index zugegriffen werden

• Einfugen und Loschen verursacht konstante Kosten

slist:• Nur vorwarts Iteratoren

• Einfach verlinkte Liste

• Kosten wie list

deque (Doppelschlange):• Ahnlich wie vector

• Auf Elemente kann uber Index zugegriffen werden operator[]

• Einfugen am Anfang und am Ende in konstanter Zeit, ansonsten in lineare Zeit

C++ Standard Template Library (STL) – p.29/41

Adaptierte Sequenzen

Verfugen uber keine Iteratoren.stack:

• LIFO

• Memeber Funktionen: empty(), size(), top(), push(newElement), pop()

• vector kann auch als Stack verwendet werden

queue:• FIFO

• Member Funktionen: empty(), size(),front(),back(), push(newElement),

pop()

priority queue:

• Oberstes Element ist immmer das großte Element

C++ Standard Template Library (STL) – p.30/41

STL Container: set

• Sammlung von Objekten (jedes Objekt kommt nur einmal vor)

• set ist immer geordnet (Objekte mussen operator<()

implementiert haben)

• Optimiert fur Einfuge- und Loschoperationen undSuchoperationen

• Instantiierung: std::set<int> set_one;

std::set<int, std::greater<int> > set_two;

• Einfugen nur mit insert: std::set<int> set_one;

std::set<int, std::greater<int> > set_two;

C++ Standard Template Library (STL) – p.31/41

STL Container: Mengenoperationen auf set

• Subset Test:includes(a.begin(), a.end(), b.begin(), b.end())

• set_union()

• set_intersection()

• set_difference()

• set_symmetric_difference()

C++ Standard Template Library (STL) – p.32/41

Weitere Assoziative Container

• set

• map

• multiset

• multimap

• hash set

• hash map

• hash multiset

• hash multimap

• hash (Funktion)

C++ Standard Template Library (STL) – p.33/41

Algorithmen

• Non-mutating algorithms

• Mutating algorithms

for each: Wendet eine Funktion auf alle Elemente an:template <class Arg>

class out_times_x : private unary_function<Arg,void>

{

private:

Arg multiplier;

public:

out_times_x(const Arg& x) : multiplier(x) { }

void operator()(Arg& x)

{

cout << x * multiplier << " " << endl;

}

};

for_each(v.begin(), v.end(), f2);

C++ Standard Template Library (STL) – p.34/41

Non-mutuating: find, find if

• find:list<int>::iterator result = find(L.begin(),

L.end(), 7);

• find if:

struct isLeapYear {

bool operator()(unsigned int year) const {

if (0 == year % 400) return true;

if (0 == year % 100) return false;

if (0 == year % 4) return true;

return false;

}

};

list<int>::iterator firstLeap =

find_if(aList.begin(), aList.end(), isLeapYear());

C++ Standard Template Library (STL) – p.35/41

Non-mutuating: adjacent find, find first of

adjacent if: findet nebeneinander liegende Elemente:int A[] = {1, 2, 3, 3, 4, 6, 5, 7, 8};

const int N = sizeof(A) / sizeof(int);

const int* p = adjacent_find(A, A + N, greater<int>());

const int* q = adjacent_find(A, A + N);

find first of:const char* WS = "\t\n ";

const int n_WS = strlen(WS);

char* s = "This sentence contains five words.";

char* end = find_first_of(s, s + strlen(s),

WS, WS + n_WS);

WS, WS + n_WS);

printf("First word of s: %.*s\n", end - s, s);

C++ Standard Template Library (STL) – p.36/41

Weiter Non-mutating Algorithmen

• count

• count_if

• mismatch

• equal

• search: findet die erste Subsequenzen:search(a.begin(), a.end(), b.begin(), b.end());

• search_n:int* result = search_n(first, last, count, val);

• find_end: findet die letzte Subsequenzen

C++ Standard Template Library (STL) – p.37/41

Mutating Algorithmen

• copy:copy(v.begin(), v.end(), ostream_iterator<int>(cout, ));

• copy n:copy(v.begin(), 3, l.begin())

• copy backward:copy_backward(X.begin(), X.begin() + 3, X.end());

1 2 3 4 5 0 0 0 0 0 0 0 0 0

1 2 3 4 5 0 0 0 0 0 0 1 2 3

• swap, iter swap, swap ranges:swap(x, y);

swap_ranges(V1.begin(), V1.end(), V2.begin());

• transform: transform(V1.begin(), V1.end(), V2.begin(), V3.begin(),

plus<int>()); V1: 1 1 1 1 1 1

V2: 2 2 2 2 2

V3: 3 3 3 3 3

C++ Standard Template Library (STL) – p.38/41

Weitere: Mutating Algorithmen

• fill, fill n

• generate, generate n

• remove, remove if, remove copy, remove copy if

• unique, unique copy1 3 3 3 2 2 1

1 3 2 1

• reverse, reverse copy

• rotate, rotate copy

• random shuffle, random sample, random sample n

C++ Standard Template Library (STL) – p.39/41

Weitere Algorithmen

Sortieren:

• sort, stable sort, partial sort, partial sort copy

• is sorted

• nth element

Binary search (sortierte Container):

• lower bound, upper bound, equal range, binary search

Mergen:

• merge: zwei sortierte Container zu einem sortierten

• inplace merge1 3 5 7 2 4 6 8

1 2 3 4 5 6 7 8

Mengen Operationen:

• includes, set union, set intersection, set difference,set symmetric difference

C++ Standard Template Library (STL) – p.40/41

Referenzen

• http://www.sgi.com/tech/stl/

• http://www.roguewave.com/support/docs/leif/foundation/html/stdlibug/booktoc.html

C++ Standard Template Library (STL) – p.41/41