Standard Template Library

Last updated

The Standard Template Library (STL) is a software library originally designed by Alexander Stepanov for the C++ programming language that influenced many parts of the C++ Standard Library. It provides four components called algorithms , containers , functions , and iterators . [1]

Contents

The STL provides a set of common classes for C++, such as containers and associative arrays, that can be used with any built-in type and with any user-defined type that supports some elementary operations (such as copying and assignment). STL algorithms are independent of containers, which significantly reduces the complexity of the library.

The STL achieves its results through the use of templates. This approach provides compile-time polymorphism that is often more efficient than traditional run-time polymorphism. Modern C++ compilers are tuned to minimize abstraction penalties arising from heavy use of the STL.

The STL was created as the first library of generic algorithms and data structures for C++, with four ideas in mind: generic programming, abstractness without loss of efficiency, the Von Neumann computation model, [2] and value semantics.

The STL and the C++ Standard Library are two distinct entities. [3]

History

In November 1993 Alexander Stepanov presented a library based on generic programming to the ANSI/ISO committee for C++ standardization. The committee's response was overwhelmingly favorable and led to a request from Andrew Koenig for a formal proposal in time for the March 1994 meeting. The committee had several requests for changes and extensions and the committee members met with Stepanov and Meng Lee to help work out the details. The requirements for the most significant extension (associative containers) had to be shown to be consistent by fully implementing them, a task Stepanov delegated to David Musser. A proposal received final approval at the July 1994 ANSI/ISO committee meeting. Subsequently, the Stepanov and Lee document 17 was incorporated into the ANSI/ISO C++ draft standard (1, parts of clauses 17 through 27).

The prospects for early widespread dissemination of the STL were considerably improved with Hewlett-Packard's decision to make its implementation freely available on the Internet in August 1994. This implementation, developed by Stepanov, Lee, and Musser during the standardization process, became the basis of many implementations offered by compiler and library vendors today.

Composition

Containers

The STL contains sequence containers and associative containers. The containers are objects that store data. The standard sequence containers include vector, deque, and list. The standard associative containers are set, multiset, map, multimap, hash_set, hash_map, hash_multiset and hash_multimap. There are also container adaptorsqueue, priority_queue, and stack, that are containers with specific interface, using other containers as implementation.

ContainerDescription
Simple containers
pairThe pair container is a simple associative container consisting of a 2-tuple of data elements or objects, called 'first' and 'second', in that fixed order. The STL 'pair' can be assigned, copied and compared. The array of objects allocated in a map or hash_map (described below) are of type 'pair' by default, where all the 'first' elements act as the unique keys, each associated with their 'second' value objects.
Sequences (arrays/linked lists): ordered collections
vector a dynamic array, like C array (i.e., capable of random access) with the ability to resize itself automatically when inserting or erasing an object. Inserting an element to the back of the vector at the end takes amortized constant time. Removing the last element takes only constant time, because no resizing happens. Inserting and erasing at the beginning or in the middle is linear in time.

A specialization for type bool exists, which optimizes for space by storing bool values as bits.

lista doubly linked list; elements are not stored in contiguous memory. Opposite performance from a vector. Slow lookup and access (linear time), but once a position has been found, quick insertion and deletion (constant time).
slist
a singly linked list; elements are not stored in contiguous memory. Opposite performance from a vector. Slow lookup and access (linear time), but once a position has been found, quick insertion and deletion (constant time). It has slightly more efficient insertion and deletion, and uses less memory than a doubly linked list, but can only be iterated forwards. It is implemented in the C++ standard library as forward_list.
deque (double-ended queue )a vector with insertion/erase at the beginning or end in amortized constant time, however lacking some guarantees on iterator validity after altering the deque.
Container adaptors
queue Provides FIFO queue interface in terms of push/pop/front/back operations.

Any sequence supporting operations front(), back(), push_back(), and pop_front() can be used to instantiate queue (e.g. list and deque).

priority queue Provides priority queue interface in terms of push/pop/top operations (the element with the highest priority is on top).

Any random-access sequence supporting operations front(), push_back(), and pop_back() can be used to instantiate priority_queue (e.g. vector and deque). It is implemented using a heap.

Elements should additionally support comparison (to determine which element has a higher priority and should be popped first).

stack Provides LIFO stack interface in terms of push/pop/top operations (the last-inserted element is on top).

Any sequence supporting operations back(), push_back(), and pop_back() can be used to instantiate stack (e.g. vector, list, and deque).

Associative containers: unordered collections
set a mathematical set; inserting/erasing elements in a set does not invalidate iterators pointing in the set. Provides set operations union, intersection, difference, symmetric difference and test of inclusion. Type of data must implement comparison operator < or custom comparator function must be specified; such comparison operator or comparator function must guarantee strict weak ordering, otherwise behavior is undefined. Typically implemented using a self-balancing binary search tree.
multisetsame as a set, but allows duplicate elements (mathematical multiset).
map an associative array; allows mapping from one data item (a key) to another (a value). Type of key must implement comparison operator < or custom comparator function must be specified; such comparison operator or comparator function must guarantee strict weak ordering, otherwise behavior is undefined. Typically implemented using a self-balancing binary search tree.
multimapsame as a map, but allows duplicate keys.
hash_set
hash_multiset
hash_map
hash_multimap
similar to a set, multiset, map, or multimap, respectively, but implemented using a hash table; keys are not ordered, but a hash function must exist for the key type. These types were left out of the C++ standard; similar containers were standardized in C++11, but with different names (unordered_set and unordered_map).
Other types of containers
bitsetstores series of bits similar to a fixed-sized vector of bools. Implements bitwise operations and lacks iterators. Not a sequence. Provides random access.
valarrayAnother array data type, intended for numerical use (especially to represent vectors and matrices); the C++ standard allows specific optimizations for this intended purpose. According to Josuttis, valarray was badly designed, by people "who left the [C++ standard] committee a long time before the standard was finished", and expression template libraries are to be preferred. [4] A proposed rewrite of the valarray part of the standard in this vein was rejected, instead becoming a permission to implement it using expression template. [5]

Iterators

The STL implements five different types of iterators. These are input iterators (that can only be used to read a sequence of values), output iterators (that can only be used to write a sequence of values), forward iterators (that can be read, written to, and move forward), bidirectional iterators (that are like forward iterators, but can also move backwards) and random-access iterators (that can move freely any number of steps in one operation).

A fundamental STL concept is a range which is a pair of iterators that designate the beginning and end of the computation, and most of the library's algorithmic templates that operate on data structures have interfaces that use ranges. [6]

It is possible to have bidirectional iterators act like random-access iterators, so moving forward ten steps could be done by simply moving forward a step at a time a total of ten times. However, having distinct random-access iterators offers efficiency advantages. For example, a vector would have a random-access iterator, but a list only a bidirectional iterator.

Iterators are the major feature that allow the generality of the STL. For example, an algorithm to reverse a sequence can be implemented using bidirectional iterators, and then the same implementation can be used on lists, vectors and deques. User-created containers only have to provide an iterator that implements one of the five standard iterator interfaces, and all the algorithms provided in the STL can be used on the container.

This generality also comes at a price at times. For example, performing a search on an associative container such as a map or set can be much slower using iterators than by calling member functions offered by the container itself. This is because an associative container's methods can take advantage of knowledge of the internal structure, which is opaque to algorithms using iterators.

Algorithms

A large number of algorithms to perform activities such as searching and sorting are provided in the STL, each implemented to require a certain level of iterator (and therefore will work on any container that provides an interface by iterators). Searching algorithms like binary_search and lower_bound use binary search and like sorting algorithms require that the type of data must implement comparison operator < or custom comparator function must be specified; such comparison operator or comparator function must guarantee strict weak ordering. Apart from these, algorithms are provided for making heap from a range of elements, generating lexicographically ordered permutations of a range of elements, merge sorted ranges and perform union, intersection, difference of sorted ranges.

Functors

The STL includes classes that overload the function call operator (operator()). Instances of such classes are called functors or function objects. Functors allow the behavior of the associated function to be parameterized (e.g. through arguments passed to the functor's constructor) and can be used to keep associated per-functor state information along with the function. Since both functors and function pointers can be invoked using the syntax of a function call, they are interchangeable as arguments to templates when the corresponding parameter only appears in function call contexts.

A particularly common type of functor is the predicate. For example, algorithms like find_if take a unary predicate that operates on the elements of a sequence. Algorithms like sort, partial_sort, nth_element and all sorted containers use a binary predicate that must provide a strict weak ordering, that is, it must behave like a membership test on a transitive, non-reflexive and asymmetric binary relation. If none is supplied, these algorithms and containers use less by default, which in turn calls the less-than-operator <.

Criticisms

Quality of implementation of C++ compilers

The Quality of Implementation (QoI) of the C++ compiler has a large impact on usability of the STL (and templated code in general):

Other issues

Implementations

See also

Notes

  1. Holzner, Steven (2001). C++ : Black Book. Scottsdale, Ariz.: Coriolis Group. p. 648. ISBN   1-57610-777-9. The STL is made up of containers, iterators, function objects, and algorithms
  2. Musser, David (2001). STL tutorial and reference guide: C++ programming with the standard template library. Addison Wesley. ISBN   0-201-37923-6.
  3. Lightness Races in Orbit (5 March 2011). "What's the difference between "STL" and "C++ Standard Library"?". Stack Overflow. Retrieved 21 October 2021.
  4. Josuttis, Nicolai M. (1999). The C++ Standard Library: A Tutorial and Handbook . Addison-Wesley Professional. p.  547. ISBN   9780201379266.
  5. Vandevoorde, David; Josuttis, Nicolai M. (2002). C++ Templates: The Complete Guide. Addison Wesley. ISBN   0-201-73484-2.
  6. Stepanov, Alexander; Lee, Meng (31 October 1995). "The Standard Template Library" (PDF). Retrieved 16 December 2018. Most of the library's algorithmic templates that operate on data structures have interfaces that use ranges. A range is a pair of iterators that designate the beginning and end of the computation. [...] in general, a range [i, j) refers to the elements in the data structure starting with the one pointed to by i and up to but not including the one pointed to by j. Range [i, j) is valid if and only if j is reachable from i.
  7. Adrian Stone. "Minimizing Code Bloat: Template Overspecialization".
  8. Meyers, Scott (2005). Effective C++ Third Edition – 55 Specific Ways to Improve Your Designs. Addison Wesley. ISBN   0-321-33487-6.
  9. Sutter, Herb; Alexandrescu, Andrei (2004). C++ Coding Standards: 101 Rules, Guidelines, and Best Practices. Addison-Wesley. ISBN   0-321-11358-6.
  10. Andrei Alexandrescu (6 May 2009). "Iterators Must Go" (PDF). BoostCon 2009. Retrieved 19 March 2011.
  11. Matthew Wilson (February 2004). "Callback Enumeration APIs & the Input Iterator Concept". Dr. Dobb's Journal .
  12. Bjarne Stroustrup (2000). The C++ Programming Language (3rd ed.). Addison-Wesley. ISBN   0-201-70073-5.:p.530
  13. More STL algorithms (revision 2)
  14. "Apache C++ Standard Library". stdcxx.apache.org. Retrieved 1 March 2023.

Related Research Articles

Templates are a feature of the C++ programming language that allows functions and classes to operate with generic types. This allows a function or class declaration to reference via a generic variable another different class without creating full declaration for each of these different classes.

<span class="mw-page-title-main">C++</span> General-purpose programming language

C++ is a high-level, general-purpose programming language created by Danish computer scientist Bjarne Stroustrup. First released in 1985 as an extension of the C programming language, it has since expanded significantly over time; as of 1997 C++ has object-oriented, generic, and functional features, in addition to facilities for low-level memory manipulation. It is almost always implemented as a compiled language, and many vendors provide C++ compilers, including the Free Software Foundation, LLVM, Microsoft, Intel, Embarcadero, Oracle, and IBM.

Generic programming is a style of computer programming in which algorithms are written in terms of data types to-be-specified-later that are then instantiated when needed for specific types provided as parameters. This approach, pioneered by the ML programming language in 1973, permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplicate code.

In object-oriented programming, the iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container's elements. The iterator pattern decouples algorithms from containers; in some cases, algorithms are necessarily container-specific and thus cannot be decoupled.

In computer programming, an iterator is an object that enables a programmer to traverse a container, particularly lists. Various types of iterators are often provided via a container's interface. Though the interface and semantics of a given iterator are fixed, iterators are often implemented in terms of the structures underlying a container implementation and are often tightly coupled to the container to enable the operational semantics of the iterator. An iterator performs traversal and also gives access to data elements in a container, but does not itself perform iteration.

Template metaprogramming (TMP) is a metaprogramming technique in which templates are used by a compiler to generate temporary source code, which is merged by the compiler with the rest of the source code and then compiled. The output of these templates can include compile-time constants, data structures, and complete functions. The use of templates can be thought of as compile-time polymorphism. The technique is used by a number of languages, the best-known being C++, but also Curl, D, Nim, and XL.

In computer science, a set is an abstract data type that can store unique values, without any particular order. It is a computer implementation of the mathematical concept of a finite set. Unlike most other collection types, rather than retrieving a specific element from a set, one typically tests a value for membership in a set.

In the C++ programming language, the C++ Standard Library is a collection of classes and functions, which are written in the core language and part of the C++ ISO Standard itself.

In computer programming, a function object is a construct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax. In some languages, particularly C++, function objects are often called functors.

In computer science, a multimap is a generalization of a map or associative array abstract data type in which more than one value may be associated with and returned for a given key. Both map and multimap are particular cases of containers. Often the multimap is implemented as a map with lists or sets as the map values.

sort is a generic function in the C++ Standard Library for doing comparison sorting. The function originated in the Standard Template Library (STL).

In the C++ Standard Library, the algorithms library provides various functions that perform algorithmic operations on containers and other sequences, represented by Iterators.

In generic programming, a concept is a description of supported operations on a type, including syntax and semantics. In this way, concepts are related to abstract types but concepts do not require a subtype relationship.

In the programming language C++, unordered associative containers are a group of class templates in the C++ Standard Library that implement hash table variants. Being templates, they can be used to store arbitrary elements, such as integers or custom classes. The following containers are defined in the current revision of the C++ standard: unordered_set, unordered_map, unordered_multiset, unordered_multimap. Each of these containers differ only on constraints placed on their elements.

The erase–remove idiom is a common C++ technique to eliminate elements that fulfill a certain criterion from a C++ Standard Library container.

In C++ computer programming, allocators are a component of the C++ Standard Library. The standard library provides several data structures, such as list and set, commonly referred to as containers. A common trait among these containers is their ability to change size during the execution of the program. To achieve this, some form of dynamic memory allocation is usually required. Allocators handle all the requests for allocation and deallocation of memory for a given container. The C++ Standard Library provides general-purpose allocators that are used by default, however, custom allocators may also be supplied by the programmer.

Concepts are an extension to the templates feature provided by the C++ programming language. Concepts are named Boolean predicates on template parameters, evaluated at compile time. A concept may be associated with a template, in which case it serves as a constraint: it limits the set of arguments that are accepted as template parameters.

In computing, sequence containers refer to a group of container class templates in the standard library of the C++ programming language that implement storage of data elements. Being templates, they can be used to store arbitrary elements, such as integers or custom classes. One common property of all sequential containers is that the elements can be accessed sequentially. Like all other standard library components, they reside in namespace std.

In C++, associative containers refer to a group of class templates in the standard library of the C++ programming language that implement ordered associative arrays. Being templates, they can be used to store arbitrary elements, such as integers or custom classes. The following containers are defined in the current revision of the C++ standard: set, map, multiset, multimap. Each of these containers differ only on constraints placed on their elements.

Although C++ is one of the most widespread programming languages, many prominent software engineers criticize C++ for being overly complex and fundamentally flawed. Among the critics have been: Robert Pike, Joshua Bloch, Linus Torvalds, Donald Knuth, Richard Stallman, and Ken Thompson. C++ was widely adopted and implemented as a systems language through most of its existence, it has been used to build many pieces of very important software.

References