This is a small book. The original name is "Using STL", I don't know who is written. But I feel very interesting, I will translate it in two nights. I didn't check the contents of the translated content. If you can't feel gaining in 30 minutes, then throw it. I saved a lot of things in the text. Distressed, waste me two nights. Translator: kary
Contact: karymay@163.net
STL Overview An important feature of STL is that the data structure and algorithm are separated. Although this is a simple concept, this separation does make STL become very common. For example, since STL's sort () function is fully universal, you can use it to operate almost any data set, including linked lists, containers, and arrays.
The point STL algorithm is provided as a template function. In order to distinguish between the other components, the STL algorithm is coupled in this book, such as Sort ().
Another important feature of STL is that it is not object-oriented. In order to have enough versatility, STL mainly depends on the template instead of package, inheritance, and virtual function (polymorphism) - OOP. You can't find any obvious inheritance relationships in STL. This seems to be a reverse, but this is exactly a wide veneer of the STL's components. In addition, since the STL is a template, the use of the inline function makes the generated code short and efficient.
prompt
Make sure that at least -O optimization is used in compilation using the STL to ensure inline expansion. STL provides a large number of templates and functions that can be used in OOP and regular programming. About 50 algorithms of all STL are fully common and do not rely on any specific data type. The following section describes three basic STL components:
1) The iterator provides a way to access objects in the container. For example, a pair of iterators can specify a certain range of objects in the List or Vector. The iterator is like a pointer. In fact, the C pointer is also an iterator. However, iterators can also be class objects that define Operator * () and other methods of operators similar to pointer.
2) The container is a data structure, such as List, Vector, and Deques, provided in a template class. In order to access the data in the container, it can be used by the iterator output from the container class.
3) The algorithm is a template function used to operate data in the container. For example, STL uses sort () to sort the data in a vector, search with the object in a list. The function itself has nothing to do with the structure and type of the data they operate, so they can be used on any data structure from a simple array to a highly complex container.
In order to avoid conflicts with other header files, STL's header files no longer use conventional .h extensions. In order to include the standard String class, iterator and algorithm, with the following indicator:
#include
#include
#include
If you view the STL's header file, you can see the header file like Iterator.h and STL_ITerator.h. Since these names may differ between various STL implementations, you should avoid using these names to reference these headers. In order to ensure portability, the file name of the corresponding no .h suffix is used. Table 1 lists the header files of the most commonly used containers. The table is incomplete, for other header files, I will introduce in this chapter and the next chapter.
Table 1. STL header files and container classes
#include container class list
Although your compiler may not implement the namespace, you can still use them. In order to use STL, the following indicator can be inserted into your source code file, typically behind all #include indicators:
Using namespace std;
The iterator iterator provides an access method of an object in a container and defines the range of objects in the container. The iterator is like a pointer. In fact, the C pointer is also an iterator. However, iterator is not just a pointer, so you can't think they must have address values. For example, an array index may also be considered an iterator.
Iterator has a variety of different creative methods. The program may create an iterator as a variable. A STL container class may create an iterator in order to use a specific type of data. As a pointer, you must use the * Operator class to obtain data. You can also use other mathematical operators such as . Typical, operators are used to increment iterators to access the next object in the container. If the iterator reaches the back of the last element in the container, the iterator becomes a PAST-The-End value. Using a PAST-The-End is worth a pointer to access the object is illegal, it seems that it is just like a NULL or the initialized pointer.
prompt
STL does not guarantee an iterator from another iterator. For example, when you are sorted in a collection, if you specify two iterators in different structures, the second iterator cannot arrive from the first iterator, at which time the program is destined to fail. This is a price of STL flexibility. STL does not guarantee unreasonable errors.
The type of iterator For STL data structures and algorithms, you can use five iterators. The following is a brief explanation of these five types:
· Input Iterators provide read-only access to data.
· Output Iterators provides only access to data
· Forward Iterators provides read and write operations and advances the iterator forward.
· Bidirectional Iterators provides read and write operations and can operate forward and backward.
· Random Access Iterators provides read and write operations and can be randomly moved in the data.
Although the details of different STL implementations are different, it is still possible to imagine the above inheritance relationship. In this sense, the following iterator inherits the iterator from the top. Due to this inheritance relationship, you can use a Forward iterator as an Output or Input iterator. Similarly, if an algorithm requires a bidirectional iterator, you can only use this type and random access iterator.
The pointer iterator is displayed as the micrographer below, and a pointer is also an iterator. The program also shows a main feature of the STL - it is not only available for its own class type, and can also be used for any C or C type. Listing 1, iterdemo.cpp, showing how to use the pointer as an iterator for the STL's Find () algorithm to search for a normal array. Table 1. IterDemo.cpp
#include
The overall number of sizes is defined in the program. Since it is a global variable, the runtime array automatically initials to zero. The following statement will set to 50 at the index 20 position, and use the find () algorithm to search for value 50:
IARRAY [20] = 50; int * ip = find (IARRAY, IARRAY SIZE, 50); the Find () function accepts three parameters. The first two define the scope of the search. Because the C and C arrays are equivalent to the pointers, the expression IARRAY points to the first element of the array. The second parameter IARRAY size is equivalent to the last-the-End value, which is the back position of the last element in the array. The third parameter is the value to be positioned, that is, 50. The Find () function returns the same type of iterator as the first two parameters, which is a pointer IP pointing to integers.
prompt
You must remember that STL uses templates. Therefore, the STL function automatically constructs according to the data type they use.
In order to determine if the Find () is successful, the IP and PAST-the-End value are tested in the example:
IF (IP == IARRAY SIZE) ... If the expression is true, it is indicated that there is no specified value within the search. Otherwise, point to a legal object's pointer, then display ::
Cout << * IP << "Found in Array" << Endl; Test Function Return Value and NULL is incorrect. Don't use it below:
INT * IP = Find (IARRAY, IARRAY SIZE, 50); if (ip! = null) ... // ??? INCORRECT When using the STL function, can only test whether the IP is and the pAST-the-End value is equal. Although IP in this example is a C pointer, the usage must also comply with the rules of the STL iterator.
Container iterators Although the C pointer is also an iterator, more is more than container iterators. The container iterator usage is the same as IterDemo.cpp, but the iterator is declared that the pointer variable is different, you can use the container class method to get an iterator object. Two typical container methods are begin () and end (). They represent the entire container range in most containers. Some other containers also provide reverse iterators using Rbegin () and rend () methods to specify the range of objects in the reverse order. The following program creates a vector container (STL and array equivalent object) and searches for it using iterators. The program is the same as the program in the previous chapter.
Listing 2. vectDemo.cpp
#include
Cout << "Vector Contains Value" << * INTITER << Endl; Constant iterator and pointer, you can assign an iterator. For example, first stipulating an iterator:
Vector first; this statement creates an iterator of a Vector
First = intVector.begin (); * first = 123; This assignment is allowed for most container classes, except for read-only variables. In order to prevent the error, it can be applied to the iterator:
Const Vector
Another kind of prevention of data is changed to decrease the container as a Const type.
"Yeah!" In the VC, the correct meaning is that the correct meaning is that the object is constant instead of whether it points to the object is not allowed, like int * const p; it seems that this author does not understand
Programming using iterators You have seen some examples of iterators, and now we will pay attention to how each particular iterator is used. Since the use iterator requires knowledge about STL container classes and algorithms, you may need to retrieve this chapter after reading the following two chapters.
Enter an iterator input iterator is the most common type. The input iterator can be used at least == and! = Testing, etc.; use * to access data; use operation to recruit iterators to the next element or reach the PAST-the-End value.
To understand how iterators and STL functions use them, now look at the definition of the Find () template function: Template
note
In the Find () algorithm, note if first and last point to different containers, the algorithm may fall into a dead cycle.
Output iterators Output iterators defaults are written only, usually used to copy data from one location to another. Since the output iterator cannot read objects, you will not use it in any search and other algorithms. To read a copy value, you must use another input iterator (or its inheritance iterator).
Listing 3. Outiter.cpp
#include
When using a copy () algorithm, you must ensure that the target container has a large space, or the container itself is automatically expanded.
The prior to tendering the prior to the prior to read and write the data value and can advance to the next value. But it can't be decremented. The replace () algorithm shows the usage method of the prior gemold.
template
Replace (vdouble.begin (), vdouble.end (), 1.5, 3.14159); two-way iterator bidirectional iterator requirements can be increased. If the Reverse () algorithm requires two two-way iterators as parameters:
Template
Reverse (vdouble.begin (), vdouble.end ()); Random Access Iterator Random Access Itecher Accesses Data in any order and can be used to read and write data (not C pointer is also random access iterators). STL sorting and search functions use random access iterators. Random access iterators can use the relationship operation comparison. The random_shuffle () function randomly disrupts the original order. Declared as:
Template
Random_shuffle (vdouble.begin (), vdouble.end ()); Iterator Technology To learn to use iterators and containers and algorithms, you need to learn the following new technologies.
A lot of examples of flow and iterator This book uses the I / O state of statement to read and write data. E.g:
Int value; cout << "Enter value:"; cin >> value; cout << "You entered" << value << Endl; for iterators, there is another way to use flow and standard functions. The point of understanding is to treat the input / output stream as a container. Therefore, any algorithm that accepts iterator parameters can work with the stream.
Listing 4. Outstrm.cpp
#include
$ g outstrm.cpp $ ./a.outbefore sorting677 722 686 238 964 397 251 118 11 312AFTER SORTING11 118 238 251 312 397 677 686 722 964 This is the magical side of STL "indeed magical". To define the output flow, STL provides template class OSTREAM_ITERATOR. This class's constructor has two parameters: an Ostream object and a string value. Therefore, you can create an iterator object as simply as follows:
Ostream_iterator
Insert an iterator Insert iterator is used to insert the value into the container. They are also called an adapter because they adapt to a container or converted into an iterator and is used in the algorithm such as copy (). For example, a program defines a linked list and a vector container:
List
• The normal insert is inserted into the front of any object of the container.
· Front INSERTERS inserts the object to the front of the dataset - for example, the linked list header.
· Back INSERTERS is inserted into the tail of the collection - for example, the tail of the vector, causing the vector container extension.
Using an inserting iterator may cause other objects in the container to move positions, thus makes existing iterators illegally. For example, inserting an object into the vector container will cause other values to move the position to make a space. In general, it is more effective in inserting an icon list because they do not cause other objects to move.
Listing 5. INSERT.CPP
#include Using Namespace Std; Int IaRray [5] = {1, 2, 3, 4, 5}; Void Display (List
$ G Insert.cpp $ ./a.outbefore Find and Copy5 4 3 2 1AFTER FIND AND COPY5 4 1 2 3 2 1 You can replace the Front_Insert to try back_inserter.
If you use Find () to find a value that does not exist in the list, for example, 99. Since Past-the-end value is set at this time. The final copy () function attached the value of the IARRAY to the rear of the linked list.
The mixed iterator function is very useful in the operation involving the container and algorithm, and there are two iterator functions:
· Advance () Adds or decreases iterators as specified.
· Distance () Returns the number of operations required to reach an iterator (increment) operation.
E.g:
List
The distance () function is iterative, that is, it increments the third parameter. Therefore, you must initialize this parameter. This parameter is not initialized to fail.
Functions and Function Objects STL, the function is called an algorithm, which is more common compared to the standard C library function. The STL algorithm is implemented as a template class or template function by overloading the Operator () function. These classes are used to create a function object, perform a wide variety of operations in the container. The following sections explain how to use functions and function objects.
Functions and assertions often require user-defined operations in the container. For example, you might want to traverse all objects of all objects in a container can call our function. E.g
#include
TanyClass Object; // Construct ObjectObject (); // Calls TanyClass :: Operator () () FunctionFOR_EACH (v.begin (), v.end (), object); STL defines several function objects. Since they are templates, they can be used for any type, including the intrinsic data type inherent in C / C , such as long. Some function objects can see its use from the name, such as Plus () and multiplies (). Similar greater () and less-equal () are used to compare two values. note
Some versions of ANSI C define the Times () function object, while GNU C names it Multiplies (). The header file
An application of a useful function object is an Accumulate () algorithm. This function calculates the sum of all values in the container. Remember that such a value is not necessarily a simple type, by overloading Operator () or class object.
Listing 8. Accum.cpp
#include
$ G accum.cpp $ ./a.outsum of values == 55Product Of VALUES == 3628800 "Note Usage of Accumulate () of the function object. Accumulate () Calculate the objects of the objects and the third parameter in each container as the parameters of the Multiplies function object, Multiplies (1, v). The source code of these templates in the VC is as follows:
// Template Function Accumulate
Template
_Ty accumulate (_ii _f, _ii _l, _ty _v)
{for (; _f! = _l; _ f)
_V = _v * _f;
Return (_V);} // template function Accumulate with binop
Template
_Ty accumulate (_ii _f, _ii _l, _ty _v, _BOP _B)
{for (; _f! = _l; _ f)
_V = _b (_v, * _f);
Return (_V);
// Template struct binary_function
Template
Struct binary_function {
TYPEDEF _A1 First_Argument_type;
TYPEDEF _A2 SECOND_ARGUMENT_TYPE;
Typedef _r result_type;
}
// Template struct multiplies
Template
Struct Multiplies: binary_function <_ty, _ty, _ty> {
_Ty operator () (const _ty & _x, const _ty & _y) const
{return (_x * _y);}
}
Introduction: If you want to know how STL is implemented, the best way is to write a simple program, put the template source code involved in the program to COPY, slightly finish, you can understand. So there is no need to buy a book such as "STL source profiling", and those books may waste time. "
A class of useful function objects is "generator". Such functions have their own memory, that is, it can remember a value from the previous call. For example, a random number generator function.
Ordinary C programmers use static or global variables "Memory" last call results. But the disadvantage of this is that the function cannot be separated from its data. "There is also a disadvantage to use TLS to thread security." Obviously, use classes to encapsulate a piece: "Memory" is safer and reliable. Let's take a look at the example:
Listing 9. randfunc.cpp
#include
Pointer_to_unary_function
Random_shuffle (v.begin (), v.end (), PTR_RANDINT; in this example, generators are just a simple calls the RAND () function. A little hassle about constant quotes (not translated, VC will be removed under the example)
The example of the generator function class object will indicate the use of generator function class objects.
Listing 10. Fiborand.cpp
#include
} Compile operation and output is as follows: $ g fiborand.cpp $ ./a.outfibonacci random number generatorusing random_shuffle and a function ObjectBefore shuffle: 1 2 3 4 5 6 7 8 9 10AFTER SHUFFLE: 6 8 5 4 3 7 10 1 9 Use RAND_SHUFFLE with a completely unreasonable method. The Fibonacci generator package is in a class, which can remember the results from previous "use". In this example, class FIBORAND maintains an array and two index variables I and J.
FIBORAND class inherits from the unary_function () template:
Template
Binder Function Object A binder uses another function object F () and parameter values V Create a function object. The bound function object must be a binocular function, that is, there are two parameters, A and B. Help in STL is:
· Bind1st () creates a function object that will value the value V as the first parameter A.
· BIND2ND () Creates a function object that will value Value V as the second parameter B.
For example, as follows:
Listing 11. Binder.cpp
#include using namespace std; // DataINT IARRAY [10] = {1, 2, 3, 4, 5, 6, 7, 8 , 9, 10}; List
Bind1st (Greater
8> Q The q expression is an object in the container. Therefore, complete expressions
Count_if (alist.egin (), alist.end (), bind1st (Greater
Negative function objects The NEGATOR function object is created from another function object. If the original function returns, the negative function object returns a false. There are two negative functions: NOT1 () and NOT2 (). NOT1 () accepts a single-optical function object, and NOT2 () accepts binocular functions. Negative function objects are usually used with a gear. For example, in the last section, use bind1nd to search q <= 8: count_if (alist.begin (), alist.end (), bind1st (Greater
Start = find_if (alist.begin (), alist.end (), not1 (Bind1nd (Greater
Summary: Using the Standard Template (STL) Although many programmers are still using standard C functions, this is as if it is riding a maunting for Mercedes. Of course, it will eventually reach the target, but you waste a lot of time.
Although it is sometimes convenient to use standard C functions (such as using sprintf () to format the output). However, the C function does not use an exception mechanism to report an error, nor is it suitable for processing a new data type. Moreover, the standard C function often uses memory allocation technology, and there is no experience, which is easy to write BUG. .
The C standard library provides more secure, more flexible data set processing. STL was originally developed by Alexander Stepanov and Meng Lee in the HP Lab. Recently, the C Standards Committee adopted STL, although there is still a detail between different implementations.
The two most important features of STL: the separation of data structure and algorithm, non-objective nature. The access object is implemented by the same iterator like a pointer; the container is the data structure of the linked list, the vector, and is provided in a template; the algorithm is a function template for operation of the data in the container. Since STL is based on a template, it can be used for any data type and structure.