580 likes | 704 Vues
In this insightful guide, Ray Lischner explores the intricacies of the Standard Template Library (STL) in C++. Discover the essential concepts of containers, including sequences and associative types such as deque, list, vector, and more. Learn how to implement your own container, understand the importance of iterators, and dive into algorithms that leverage the STL's power. Whether you're a beginner or looking to deepen your understanding, this resource equips you with the knowledge needed to master STL containers effectively.
E N D
Ray Lischner lisch@cpphelp.com Writing Your Own STL Container
Who Am I? • Ray Lischner • Author • C++ in a Nutshell • Learning C++ • STL Pocket Reference • Oregon State University
What Is The STL? • A. Silly Three Letters • B. Standard Template Library • C. So That’s Life • D. Sue The Lawyers!
What Is The STL? • A. Silly Three Letters • B. Standard Template Library • C. So That’s Life • D. Sue The Lawyers!
What Is The STL? • A. Silly Three Letters • B. Standard Template Library • C. So That’s Life • D. Sue The Lawyers!
STL • Standard Template Library • Containers • deque, list, map, multimap, multiset, set, vector • string • Iterators • Algorithms
STL • Standard Template Library • Containers • deque, list, map, multimap, multiset, set, vector • string • TR1 adds: array, unordered_map, unordered_multimap, unordered_multiset, unordered_set, • Iterators • Algorithms
Experience • A. I’ve never used STL containers • B. I have used containers, iterators, and algorithms a little • C. I use containers, iterators, and algorithms often • D. I have implemented my own container
What Is a Container? • A template, parameterized on element type • Stores multiple, homogeneous elements • Characterized by complexity metrics • # of operations for insertion, deletion • # of operations for lookup
Kinds of Containers • Sequence • deque, list, vector • array • Associative • map, set • multimap, multiset • unordered_map, unordered_set • unordered_multimap, unordered_multiset
Common Standards • Standard dictates common attributes • Common sense
Container Review • Elements must be assignable, copy-constructible • T a, b • T c(a); • b = a;
Common Members • Types: • value_type, size_type, etc. • Constructors: default, copy • Destructor • Assignment operator • Relational and equality operators • Member functions • begin(), end() • size(), swap(), max_size(), empty()
Sequence Members • insert() single or multiple elements • erase() single or multiple elements • clear() entire container • sequence constructors
Integer or Not? • Insertion and construction • insert(position, x, y) • std::vector<sometype> example(x, y); • If x and y are integers • Insert or construct x copies of y • Else x and y must be iterators • Copy elements from range [x, y)
Sequence Members • Only if constant complexity • back(), pop_back(), push_back() • front(), pop_front(), push_front() • at(), operator[]
Singly-linked List template<class T> class slist { ... };
Design Decisions • Store head only? • Store head and tail? • Store size or compute as needed?
Front and Back • Sequence containers • Constant complexity • Member functions: • front(), push_front(), pop_front() • back(), push_back(), pop_back()
Container Adapters • priority_queue, queue, stack • queue • Requires back(), front(), push_back(), pop_front() • stack • Requires back(), push_back(), pop_back()
Heads and Tails • Does tail help implement adapters? • Call the head “front” or “back”?
Insertion and Erasure • Can insert after a given node • Can erase the node after a given node • Can easily erase at head
Stack vs. Queue • Stacks • head is back • Queue • head is front • tail is back
What Good Is a Tail? • push_back() • back_inserter iterator adapter
Container Size • Standard does not require constant complexity • Gotcha for std::list::size()
Splicing • std::list::splice moves nodes from one doubly-linked list to another • Splicing is fast • But explicit size data member requires linear complexity • What’s more important, size or splice?
Lazy Evaluation • Explicit size data member • Kept up-to-date after insertion, erasure • Can be marked as “unknown” after calling splice • Call to size() when size is unknown counts every node in list
More Important? • A: Optimize size() • B: Optimize splice() • C: Lazy-evaluation • D: I have a better idea
More Important? • A: Optimize size() • B: Optimize splice() • C: Lazy-evaluation • D: I have a better idea
Allocators • Second template parameter template<class T, class Alloc = ::std::allocator<T> > class slist { ... }; • Allocates/deallocates memory • Constructs/destructs nodes
Separate Allocation and Construction • allocate(number_of_items) • construct(pointer, value_to_copy) • deallocate(pointer, number_of_items) • destroy(pointer)
Rebind • Alloc<T> allocates items of type T • But slist needs to allocate nodes, not elements • Need to rebind allocator for nodes • allocator<T>::rebind<node_type>::other
Avoid Memory Leaks • new_node allocates & constructs nodes • If constructor throws, new_node should deallocate memory
Iterator • Points to one node in a list • Advances to next node • Compares with other iterators • Special value denotes “one past end”
Iterator Review • Like a smart pointer slist<int> list; slist<int>::iterator iter =list.begin(); if (not list.empty()) ++iter; if (iter != list.end()) std::cout << *iter << '\n';
Iterator Review • Five flavors • Input • Output • Forward • Bidirectional • Random Access
How Are Iterators Used? • Insertion point • Item(s) to erase • Item(s) to copy
Iterator Design • Need to store pointer to prior node • Null prior pointer when iterator at head • What about end()? • Also store pointer to current node • Null current pointer means end()
Comparing Iterators • Compare iterators by comparing current node pointers • Difficulty comparing iterator and const_iterator • See Scott Meyers’ Effective STL, Item 26 • Use a common base class
Iterator Invalidation • Certain operations render iterators invalid • Erasure • Invalidates iterators that point to the erased node • Or to the subsequent node • Insertion • Invalidates iterators that point to the insertion position
Exception Safety • Basic guarantee: list remains valid • unique • Strong guarantee: list is unchanged • sort • No-throw guarantee • swap, splice
Which Guarantee for insert of one item? • A: None • B: Basic • C: Strong • D: No throw
Which Guarantee for insert of one item? • A: None • B: Basic • C: Strong • D: No throw
Which Guarantee for insert of multiple items? • A: None • B: Basic • C: Strong • D: No throw