Note II of the C + + standard library
This blog note order is broadly organized in the order of the chapters of the C + + standard library (1th edition).
--------------------------------------------------------------------------------------------
6. STL Container
6.1-1
This section describes the common capabilities of STL containers. Most of these are prerequisites, and all STL containers must meet those conditions. The three most core competencies are:
(1) All containers provide "value semantics" rather than "reference semantics". When an element is placed in the container, the internal implementation is a copy operation, which is put inside the container. Therefore, every element of the STL container must be able to be copied. If the object you intend to store does not have a public copy constructor, or if you want a copy that is not a replica (for example, you want an element that is held together by multiple containers), then the container element can only be a pointer (point to the object). See the previous blog for one of the C + + standard library notes, section 5.10.
(2) Overall, all elements form a sequence (oder). In other words, you can traverse each element one or more times in the same order. Each container provides a function that returns an iterator, and you can iterate through the elements by using those iterators. This is the key interface that the STL algorithm relies on to survive.
(3) Generally speaking, the operation is not absolutely safe. The caller must ensure that the parameters passed to the operation function meet the requirements. Violations of these requirements, such as the use of illegal indexes, can result in undefined behavior. Usually STL itself does not throw an exception. If the user custom action called by the STL container throws an exception, it can result in a different behavior.
Common operation of containers as shown in table 6.1
6.2 Vector
The capacity of the 6.2-1 vector is important for the following two reasons:
(1) Once the memory is reconfigured, all references, pointers, and iterators associated with the vector element will fail;
(2) Memory reconfiguration is time consuming (placement can result in reconfiguration).
The capacity of the vectors does not shrink, and we can be sure that even if the element is deleted, its references, pointers, Iterators will continue to work, continuing to point to the position before the action occurred. However, the placement operation may be references, pointers, iterators failure (memory reconfiguration).
6.3 Deques
6.3-1 Deque does not support control over the timing of capacity and memory redistribution. However, Deque's memory redistribution is superior to vector because its internal structure shows that Deque does not have to replicate all elements in memory redistribution. See "STL Source Code Anatomy"
6.5 Sets and multisets (red-black tree)
There are two ways to define sorting criteria:
(1) For example: Std::set<int, std::greater<int> > coll;
In this case, the sorting criterion is part of the type. So the type system ensures that only containers with the same sorting criteria can be merged. This is the usual designation method for the sorting criteria. More precisely, the second parameter is the type of the sorting criterion, and the actual sorting criterion is the function object that the container produces (functions, or functor). To produce it, the container constructor invokes the default constructor for the collation type.
1. The element comparison action can only be used for the same type of container. In other words, the element and the collation must have the same type, or the compilation period will produce a type error. As follows:
STD::set<float> c1; // sorting Criterion-std::less<>std::set<float, std::greater<float > > C2; // sorting criterion-std::less<> ... if (C1 = = C2) // error:different Types { ...}
2. We can also use custom sorting criteria, which is also used as the collation of the pseudo-function
#include <iostream>#include<string>#include<Set>#include<algorithm>using namespacestd;classperson{ Public: stringFirstName ()Const; stringLastName ()Const; ....};/*class for function predicate*-operator () returns whether a person was less than another person*/classpersonsortcriterion{ Public: BOOL operator() (Constperson& P1,Constperson& P2)Const { /*A person was less than another person *-if the last name was less *-if the last name is equal and the first name is less*/ returnP1.lastname () < P1.lastname () | | (! (P2.lastname () < P1.lastname ()) &&P1.firstname ()<p2.firstname ()); }};intMain () {//declare set type with special sorting criteriontypedefSet<person, personsortcriterion>Personset; //create such a collectionPersonset Coll; ... //Do something with the elementsPersonset::iterator POS; for(pos = Coll.begin (); pos! = Coll.end (); + +POS) { ... } ...}
(2) defined by the constructor parameter
In this case, different sorting criteria can be applied to the same type (as in the example below), and the initial value or state of the sorting criteria can be different. This can come in handy if you get the sorting criteria for the execution period, and you need to use different sorting criteria (but the data type must be the same).
//The execution period specifies the sorting criteria, the sorting criteria are different, but the types are the same:#include <iostream>#include<Set>using namespacestd;//type for sorting criterionTemplate <classT>classruntimecmp{ Public: enumCmp_mode {normal, reverse}; Private: Cmp_mode mode; Public: //constructor for sorting criterion//-default criterion uses value normalRUNTIMECMP (Cmp_mode m =normal): Mode (m) {}//comparision of elements BOOL operator() (Constt& T1,Constt& T2)Const { returnmode = = Normal? T1 < T2:t2 <T1; } //comparision of sorting criteria BOOL operator== (Construntimecmp&RC) { returnmode = =Rc.mode; }};//type of a set that uses this sorting criteriontypedefSet<int, runtimecmp<int> >Intset;//Forward DeclarationvoidFill (intset&Set);intMain () {//Create, fill, and print set with normal element order//-Uses default sorting criterionIntset coll1; Fill (COLL1); Print_elements (COLL1,"coll1:"); //create sorting criterion with reverse element orderruntimecmp<int> Reverse_order (runtimecmp<int>:: reverse); //Create, fill, and print set with reverse element orderintset coll2 (Reverse_order); Fill (COLL2); Print_elements (Coll2,"coll2:"); //assign elements and sorting criterionCOLL1 =coll2; Coll1.insert (3); Print_elements (COLL1,"coll1:"); //just to make sure ... if(Coll1.value_comp () = =Coll2.value_comp ()) {cout<<"Coll1 and coll2 have same sorting criterion"<<Endl; } Else{cout<<"Coll1 and coll2 have different sorting criterion"<<Endl; }}voidFill (intset&Set){ //fill Insert elements in random order Set. Insert (4); Set. Insert (7); Set. Insert (5); Set. Insert (1); Set. Insert (6); Set. Insert (2); Set. Insert (5);} Output: coll1:1 2 4 5 6 7coll2:7 6 5 4 2 1coll1:7 6 5 4 3 2 1Coll1 and coll2 have same sorting criterion
1. In this program,runtimecmp<> is a simple template that provides the generalization capability of "defining a sort criterion for arbitrary types during execution". Its default constructor is sorted in ascending order with the defaults, normal, and you can also pass Runtimecmp<>::reverse to the constructor, which can be sorted in descending order.
2. Note that coll1 and coll2 have the same type (including the type int for the element and the type runtimecmp of the sorting criteria), which is the parameter type of the fill () function. Note again that the assignment operator not only assigns the element, but also assigns the ordering criteria (otherwise any assignment operation will not easily compromise the sorting criteria).
3. Note that the sorting criteria are also used for element equality validation, when the default sorting criteria is used, the two-element equality test statement is as follows:
if (! (Elem1 < ELEM2 | | elem2 < ELEM1))
There are three advantages to doing so:
A. Simply pass a parameter as the sorting criterion;
B. No need to provide operator== for element type;
C. You can have a diametrically opposed definition of "equality", but beware of confusion.
6.6 Maps and Multimaps
The element type keys and T of maps and Multimaps must meet two conditions:
(1) Key/value must have assignable (assignable) and copyable (replicable) properties;
(2) For sorting criteria, key must be comparable (comparable).
Maps,multimaps's collation definition is similar to sets,multisets. Similarly, the element's comparison action can only be used for the same type of container. In other words, the key,value of a container must have the same type as the sorting criteria, otherwise the compile time will produce a type error.
Again, the easier-to-type algorithm must not be used for associative containers, and the iterator type provided for the associative container is const iterator.
6.7 Other STL Containers
6.7-1
STL is a framework that, in addition to providing a standard container, allows you to use other data structures as containers. You can use a string or an array as an STL container, or you can write a special container yourself to meet the requirements of the feature. If you write your own container, you can still benefit from algorithms such as sorting, merging, and so on. Such a framework is an excellent example of the "Open Closed (open-closed)" Principle: Allow extensions, decline changes.
Here are three different ways to "STL" your container:
(1) The invasive approach (invasive approach) directly provides the interface required for STL containers. In particular, commonly used functions such as begin () and end (). This practice requires the container to be written in a particular way, so it is intrusive.
Take string for example:
Strings can be thought of as a container of characters, and a sequence of characters that you can move back and forth through the sequence. Therefore, the standard string class provides the STL container interface. Strings also provides the member function begin () and end (), which returns a random access iterator that can be used to traverse the entire string.
(2) The noninvasive approach (non-invasive approach)
It is up to you to write or provide special iterators as an interface between algorithms and special containers. This is a non-invasive approach that requires only the ability to "traverse all elements of a container"-a capability that any container can exhibit in some form.
Take array for example:
Arrays can be considered an STL container, but array is not a category, so member functions such as Begin () and end () are not provided, and no member functions are allowed. Here, we can only use non-invasive practices or packaging methods. Taking a non-intrusive approach is simple, you only need an object that can traverse all the elements of the value through the STL iterator interface. In fact, such an object already exists, it is a normal pointer. At the beginning of the STL design, the iterator has the same interface as the normal pointer, so you can use the normal pointer as an iterator.
(3) The wrapper approach (packing method) combines the above two methods, we can write a coat class to wrap any data structure, and display a similar interface to the STL container.
6.7-2 Hash Tables
Hash tables data structures are very important to the cluster, but because the proposal is too late to be included in the C + + standard library-"We must abort the introduction of new features at some point, start paying attention to details, or work endlessly." Hash tables related content can be found in the STL source analysis.
6.9-1
Table 6.33 provides a list of STL container capabilities.
Note II of the C + + standard library