This section is enclosed in the following, and is summarized by yourself outside the brackets.
/*************************************** **************************************** **************************************** **************************************** * ************** Study Notes-Objective STL-use STL to program a new article: miscellaneous-so-called algorithms and cooking Clause 43: use algorithms to call instead of hand-written Loops
There are three reasons:
Efficiency: algorithms are generally more efficient than loops produced by programmers.
Correctness: writing a loop is more prone to errors than calling an algorithm.
Maintainability: algorithms usually make the code clearer and more intuitive than the corresponding explicit loop.
Cla44: Use a member function instead of an algorithm of the same name.
Existence is a truth.
Clause 45: note the differences between count, find, binary_search, lower_bound, upper_bound, and interval _range.
Understand the dependencies and features of these functions.
Cla46: consider using a function object instead of a function as an algorithm parameter.
It is generally more efficient to pass the code generated by passing the STL function object-disguised as the function object-to the algorithm. The reason is inline. Another reason for replacing functions with function objects is that they can help you avoid subtle language traps.
Article 47: Avoid writing only code
Software that cannot be read or understood cannot be maintained, and software that cannot be maintained is hardly worth having. Finally, such code is completely inefficient.
Clause 48: always # include the appropriate header file
Almost all containers are in header files with the same name. For example, vector declares in <vector> and list declares in <list>. The exception is <set> and <map>. <Set> set and Multiset are declared. <map> map and multimap are declared.
All except the four algorithms are declared in <algorithm>. The exception is accumulate (see clause 37), inner_product, adjacent_difference, and partial_sum. These algorithms are declared in <numeric>.
Special iterators, including istream_iterators and istreambuf_iterators (see section 29), are declared in <iterator>.
Standard functions (such as less <t>) and function adapters (such as not1 and bind2nd) are declared in <functional>.
Cla49: Learning to crack compiler diagnostic information related to STL
For vector and string, the iterator is sometimes a pointer, So if you make an error using the iterator, the compiler diagnostic information may mention the pointer type. For example, if your source code involves vector <double>: iterator, the compiler message sometimes mentions the double * pointer. (One notable exception is when you use STL implementation from stlport and you are running in debug mode. In that case, the iterators of vector and string are not pointers at all. For more information about stlport and its debugging mode, refer to Article 50 .)
When it comes to messages of listener, front_insert_iterator, or insert_iterator, it often means that you have mistakenly called back_inserter, front_inserter, or inserter. (back_inserter returns objects of the listener type and front_inserter returns objects, inserter returns insert_iterator objects. For information on the use of these inserter, refer to Clause 30 .) If you have not called these functions, you (directly or indirectly) call some functions.
Similarly, if you get a message that mentions binder1st or binder2nd, you may mistakenly use bind1st or bind2nd. (Bind1st returns an object of the binder1st type, while bind2nd returns an object of the binder2nd type .)
The output iterator (for example, ostream_iterator, ostreambuf_iterators (see article 29), and the iterator returned from back_inserter, front_inserter, and inserter) performs output or insert work within the value assignment operator, so if you mistakenly use one of these iterator types, you are likely to get a message complaining about something in a value assignment operator you have never heard. To understand what I mean, compile this Code:
Vector <string *> V; // tries to print
Copy (V. Begin (), V. End (), // string * pointer container,
Ostream_iterator <string> (cout, "/N"); // It is treated as a string object.
You get an error message originating from the internal implementation of the STL algorithm (that is, the error caused by source code is in <algorithm>). Maybe it is the type error you tried to give the algorithm. For example, you may have uploaded an iterator of the error type. Let's take a look at how such usage errors are reported. By feeding this code to your compiler, we will be inspired (and happy !) Yourself:
List <int>: iterator I1, I2; // sets the bidirectional iterator
Sort (I1, I2); // transmits it to an algorithm that requires Random Access to the iterator.
You use common STL components such as vector, string, or for_each algorithms. The Compiler does not know what you are talking about. You may not include a required header file. As explained in Clause 48, this problem will occur when the code just transplanted to the new platform can be compiled for a long time.
Article 50: familiarize yourself with STL-related websites
Sgi stl website, http://www.sgi.com/tech/stl /.
Stlport website, http://www.stlport.org /.
Boost website, http://www.boost.org/
Http://boost.sourceforge.net //************************************* **************************************** **************************************** **************************************** *****************
Clause 1: carefully select your container
Sequential container
StandardSTLSequential container: Vector, String, deque, and list.
StandardSTLAssociated container: Set, Multiset, map, and multimap.
Non-standard sequence containerSlist and rope. Slist is a one-way linked list, and rope is essentially a heavy string. ("Rope" is a heavy "string ". Do you understand ?) You can find an overview of these non-standard (but common) containers in Clause 50.
Non-standard associated containerHash_set, hash_multiset, hash_map, and hash_multimap. In Clause 25, I checked the differences between these widely available hash table-based containers and standard associated containers.
Vector <char>Can be usedString.Clause 13 describes the potential significance of this alternative.
VectorAs a substitute for standard associated containers.As mentioned in cla23, sometimes vector can be better than standard associated containers in terms of time and space.
Several TypesStandard non-STLContainer, Including array, bitset, valarray, stack, queue, and priority_queue. Because they are non-STL containers, I rarely talk about them in this book.1. class customerlist {PRIVATE: typedef list <customer> customercontainer; // you can use typedef to replace the container type typedef customercontainer: iterator cciterator. // The same applies to customercontainer MERs; public: // limit the amount of list-specific... // information visible through}; // This interface
2. When you add an object to the container (such as through insert or push_back), The Copied object you specified is entered into the container. Therefore, we must consider the copy cost of objects and the class inheritance relationship, for example, inserting a container of the parent class template type into a subclass may cause loss of the derived part (the segmentation problem implies that the container that inserts a derived class object into the base class object is almost always wrong) 3stl containers are more civilized. They only create (by copying) the number of objects you need, and they are only done when you specify. Yes, we need to know that STL containers use copies, but don't forget the fact that they are still an improvement over arrays. Because the array has a certain meaning, it is generally necessary to specify the size, for example, char Cmax [1024]; 4. use empty () instead of checking whether size () is 0 5. clause 5: Use the interval member function instead of their single-element sibling vector <int> vec1, vec2, vec2.assign (vec1.begin, vec1.end)
6. Use "swap tricks" to fix unnecessary vacancies
String s ;... // Make s large, then erase most // of Its Characters String (s ). swap (s); // if the space occupied by S is far from that of the stored data, s will be compressed 7. general swap. exchange the content of two containers, including the iterator for exchanging them, pointers, and references. in one container, the iterator, pointer, and reference are still valid in another container after transformation and point to the same element. 8. in clause 18, avoid using vector <bool> because the vector container uses bits to represent the true and false values of a bool:
Vector <bool> * PVEC = & V [0]; // note that the pointer cannot point to a bit and can be replaced by deque <bool>. deque represents bool 9 in 1 byte. clause 21: always let the comparison function return false to the same element. Let's take a look at the following example and we can see a text parsing.
The value returned by the comparison function indicates whether an element should be located before another element in the sorting mode defined by this function. The same element should never lead the other, so the comparison function should always return false for the same element.
The actual comparison type you need is struct stringptrgreater: // This Is A validpublic binary_function <const string *, // comparison type for const string *, // Associative containers bool> {bool operator () (const string * ps1, const string * PS2) const {return * PS2 <* PS1; // return whether * PS2} // precedes * PS1 (I. E ., swap // The Order of the}; // operands
10. If we pass V to a C-style API function in this form
Void dosomething (const int * pints, size_t numints );
We can do this:
Dosomething (& V [0], V. Size ());
In order to replace the associated container analysis map with a sorted vector, the tree structure is used for storage, and the pointer pointing to the front and back nodes is stored. the pointer must occupy space.
Learn how to get iterator v. Erase * (++ RI). Base () through the reverse_iterator base ());
If you need to input one character at a time, consider using istreambuf_iterator to capture faster than istream_iterator-40% faster in my simple test. If your results are different, don't be surprised.
5. Remove is not "true" because it cannot.
Repetition is good for you:
Remove is not "true" because it cannot.
Remove does not know which container it is going to delete, but does not have a container, so it cannot call the member function. If it is "true", It is necessary 8. v. erase (remove (v. begin (), V. end (), 99), V. end (); // delete all
9. ostringstream ost; Ost <n; string STR = ost. STR ();
10. STL deque container: STL Chinese language learning site has a special article about deque, and concluded that deque is processing frontend insert, and the memory release efficiency is higher than the vector container (For details, refer to the article)
11 * use two methods to access the vector. 1. Vector: At () 2. Vector: operator [] OPERATOR [] is mainly used for compatibility with the C language. It can be operated like a C array. However, at () is our first choice because at () performs a boundary check.
12 compress a bloated vector, which is relatively simple. Use the assign of the vector to allocate the space for creating a new vector based on the actual size of the vector. For example:
Vector <int> vecbig; reserve 1000 pieces of data, and press pieces of data. Vector <int> vecsmall; vecbig. Assign (vecsmall );
13. STL source code analysis: 12.1. After reading the memory distributor and iterator, I became more admired for writing standard library predecessors, orz. The standard library is the container (data structure). Isn't the algorithm actually a program a Data Structure + algorithm? haha, the bridge between the container and the algorithm is actually an iterator, is the core part. Iterations are implemented using templates or even template-specific mechanisms. I want to know what template is special: simply add a specific restriction on the template type parameters on the common template class, such as template <typename T> class ctem; template <typename T *> specifies that the template type parameter can only accept the native pointer 12.2 and read the vector container. It mainly provides excellent memory allocation and memory pool mechanisms, which are very clever. In fact, the whole vector container is not complicated, but after you know the internal implementation principle, you naturally know that the vector container is suitable for Tail insert operations. [] operation. However, the efficiency of deletion and other operations is lower than that of list (OK, write it today, and continue next week) 14. the associated container: STL's associated container is indeed more practical: The underlying implementation is nothing more than Data Structure + Algorithm Implementation: First, you must understand the concept of the tree, at last, we went deep into the binary tree-> the balanced binary tree-> the red and black trees, set MAP Multi + set, and the underlying map is implemented by the red and black tree structures. What is a red-black tree: It generally refers to a better balance binary cable collection tree. STL adopts this structure because, after the balance of the red and black trees, it can efficiently search associated containers in non-large containers with large randomness. Let's see a bunch of attributions in the front: smart people can see that the red and black trees have their weaknesses. In the case of large data volumes and low randomness in searching, the red and black trees are not very efficient. For example, search for 100,000 specific leaf nodes from 10 thousand data containers. Whining, that's no big deal. In the key moment, we can't go out of the hash-table and the hash table. This name seems cool, but it's nothing more than a little trick. Let's take a look at a small example. In the 100,000 16-bit short integer, We need to count the number of times each number appears. What is the trick? Let's look at my dummies. Just come up with a small trick, that is, using the most basic array method. Because the maximum short value of 16 bits is the power 16 of 2, and the range is 0-65535. in this case, int iavalue [65536]; then, iavalue [I] + 1 during statistics; in this case, the final iavalue is the complete value, which includes the statistical value, which makes searching fast, as long as iavalue [I]. The purpose of this example is to tell yourself that hashtable is also implemented based on this principle, but it is more complicated. If the 16 bits in the preceding example are changed to 32 bits, then the array space of 2 32 bits and 4G is left empty. Therefore, the hash table uses a ing method to map the partition to a certain range of array spaces. Then hash again. Of course, this will cause a collision. The specific hash table collision check method will not be written here. Anyway, we probably know that the general implementation method of the hash_table hash_set associated with the STL container is OK. (for cooking, see the source code analysis algorithm next week.) 14. there are indeed many STL algorithms. First, one of them is recorded slowly: count_if, Count, find_if, find belongs to one of the types, that is, directly bringing type T without if, generally, if users write judgment functions by themselves. Generally, they just make their own imitation functions.
15. Imitation functions: As the name implies, they are just imitating functions. The general practice is to use the class overload () operator,
Greater <int> () (5, 6); the most important thing about a function imitation is compatibility: unary_function, binary_function
The common practice is template <class T> struct plus: Public unary_function <t, t>.
{}. Similar function types: logic (such as and, or), relational (equal, equal_to), algorithm (plus, minus)
16. Adapter: (copy a section ~ ~)
An adapter is an STL component used to modify interfaces of other components. It is a class template with a parameter (this parameter is the data type of the operation value ). STL defines three types of adapters: Container adapter, iterator adapter, and function adapter.
Container adapter: includes stack, queue, and priority_queue ). With the container adapter, stack can be adapted to the basic container type (vector, dequeue, list. Stack can be regarded as a special vctor, deque or list container, but its operations are still restricted by the stack attributes. Queue and priority_queue are similar. The container adapter interface is simpler, but more limited than the average container;
Iterator adapter: an STL component that modifies the interface of the iterator defined by some basic containers. Both the reverse iterator and the insert iterator belong to the iterator adapter. The iterator adapter extends the iterator function;
Function adapter: converts or modifies other function objects to extend functions. This type of adapter has a negative (equivalent to a "Non" Operation), function pointer Adapter
The STL source code analysis has finally been completed. Considering what to read in the next stage, it should be the C ++ related stuff on the Windows platform. Recently, I went to the Linux advanced environment programming, however, we still need to familiarize ourselves with the Ubuntu system before starting relevant development. At present, we are given priority to Windows. Consider whether to perform windows core programming or exception CPP.
Haha, the 11 holiday is approaching. The two books 'window core programming 'or 'exception CPP' mentioned above are also roughly finished. The former also writes a summary and adds it to the blog, while the holiday was a little time and by the way, I re-read "STL source code analysis" and had some gains. It was indeed a good book, so I decided to spend some time reviewing important chapters, by the way, it may be useful to write a summary of the iterator that took about two hours.
* Special: the so-called special version is a special version designed for further restrictions on any template parameters. Haha, this should be a reasonable explanation of the bitrate I have seen. The explanation is not enough. Let's look at the Code:
Note: The traits extractor solves the native pointer type iterator for the following reasons:
Ordinary iterator Design
Template <class T>
Struct myiter {typename t value_type; // The embedded type is described here, that is, an iterative value can be declared using this mechanism. However, this method has a vulnerability, that is, when T is a native pointer (for example, int *), this method cannot be passed, and it cannot be defined as an embedded type.
What should I do? At this time, we need to make a special appearance. Please refer:
Template <class T>
Struct iterator_traits <t *> {typedef t value_type;} Haha, This completes the native pointer, but there is still a problem. If the type is const int *, this can only be done, define one more special version
Template <class T>
Struct iterator_traits <const T *> {typedef t value_type ;}
To put it bluntly, the purpose of all these operations is to extract the type of iterator by using the compiler's derivation features of template parameters... Why is it necessary to obtain it, because the iterator type may be frequently used in algorithm application. Such as find
* The right value is not allowed to be assigned a value, and the left value is allowed to be assigned a value. As mentioned in the book, I used to evaluate such an interview question and record it by the way.
* Five types of iterators:
1. The value type is the type of the object referred to by the iterator.
2 difference type indicates the distance between two iterators
3. Content of the thing referred to by the reference type iterator (for example, vecotr <int >:: iterator ite; * ite = 5; modified the content of the container
4. pointer type returns an iterator pointing to the thing referred to by the iterator ite-> first;
5. iterator_category iterator type
You must first understand the iterator category
Input (read-only) output (write only)
Forward (read/write)
Bidirectional (bidirectional Movement)
Random (random)
Different Fall generator types apply to different algorithms and naturally have different results. The key is efficiency. For example, advandced, the same advanced (100) the random iterator is certainly faster than the input iterator.
* Each STL container provides its own iterator (because the iterator must expose its own details)
*. Feature extract: iterator_traits
* "The algorithm does not change the container size" back_inserter () does not break through this restriction. When back_inserter is used, it is not directly manipulated by the algorithm.
Container size, but the algorithm manipulated the back_inserter iterator. The iterator operation caused the container size to change.
The reason why back_inserter does not change the algorithm and does not change the container size is that ***** to make the algorithm independent from the container, so as to be more universal and truly "algorithm"
* Algorithm classification: Read-Only algorithm such as find * findfirstof, write algorithm fill, fill_n
* Sorting Algorithm