30 minutes to master STL

xiaoxiao2021-03-06  102

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 Deque list map, multimap queue, priority_queue set, multiset stack vector, vector name space Your compiler may You cannot identify the namespace. The name space seems to be an envelope, encapsulating the flag in another name. The logo is only existed in the namespace, thus avoiding conflicts with other markers. For example, there may be other libraries and program modules to define the sort () function, in order to avoid conflicts with the STL's sort () algorithm, SORT (), and other flags of STL are packaged in the namespace STD. STL's sort () algorithm compiles to std :: sort (), thereby avoiding the name conflict.

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 #include using namespace std; #define size 100int aRay [size]; int main () {aRray [20] = 50; int * ip = find (IaRray, IARRAY SIZE, 50 ); If (ip == narray size) cout << "50 not found in array" << endl; else cout << * ip << "Found in array" << endl; return 0;} is here / O Logan and STL algorithm header file (notes not .H suffix), the program tells the compiler to use the STD namespace. This line using STD namespace is optional because it can be deleted that this line will not cause the name conflict.

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 #include #include using namespace std; vector intVector (100); void main () {intVector [20] = 50; Vector :: Iterator INTITER = Find (intVector.egin (), intVector.end (), 50); if (intiter! = IntVector.end ()) cout << "Vector contains value" << * intiter << Endl; else cout << " VECTOR Does Not Contain 50 << Endl;} Note Searching the following method:

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 class. The following statement sets the iterator to the first object of the intVector and sets the object value it points to 123 ::

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 :: item = find (intVector.egin (), intVector.end (), value); if (result! = intVector.end ()) * Result = 123; //??? caveat

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 InputIterator Find (InputItitrator First, InputIte Last, Const T & Value) {While (First " ! = Last && * first! = value) first; returnax

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 #include // NEED COPY () # include // NEED Vector Using Namespace Std; Double Darray [10] = {1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9}; vector vdouble (10); int main () {Vector :: item outputIutiterator = vdouble.begin (); copy (Darray, Darray 10, OutputIterator); while (Outputiterator! = vdouble.end ()) {cout << * OutputIutiterator << endl; outputiterator ;} return 0;}

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 void replace (ForwardIterator first, ForwardIterator last, const T & old_value, const T & new_value); using replace () the [first, last] all objects is old_value in the range replaced new_value. :

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 Void Reverse (BidirectionAliterator first); use the Reverse () function to reverse the container in reverse:

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 void random_shuffle (RandomaccessIterator first); use method:

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 #include // need random (), srandom () # include // need time () # include // NEED SORT (), COPY () #include // Need Vector Using Namespace Std; Void Display (Vector & V, Const Char * S); int main () {// seed The Random Number Generator Srandom (Time (NULL)) ; // construct vector and fill with random integer value vector Collection (10); for (int i = 0; i <10; i ) collection [i] = random ()% 10000; // Display, sort And Redisplay Display (Collection, "Before Sorting"); Sort (Collection.Begin (), Collection.end ()); Display (Collection, "After Sorting"); return 0;} // Display Label S and Contents of RedIn Integer Vector Vvoid Display (Vector & V, Const Char * S) {cout << Endl << S << Endl; Copy (v.begin (), v.end (), Ostream_Iterator (COUT, "/ t")); cout << Endl;} DISPLAY () shows how to use an output stream for yourself. The following statement is transferred to the value in the container into the COUT output stream object: Copy (v.begin (), v.end (), ostream_iterator (cout, "/ t")); third parameter instantiation The ostream_iterator type, and uses it as the output destination iterator object of the Copy () function. The "/ t" string is a separator. operation result:

$ 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 (cout, "/ n") This iteration can be used with any function that accepts an output 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 DList;, by using the Front_Inserter iterator object, you can complete the object inserting the vector in the front end of the chain table with only a single copy () statement: Copy (DVector.Begin (), DVector .end (), front_inserter (dlist); three inserting iterators are as follows:

• 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 #include #include Using Namespace Std; Int IaRray [5] = {1, 2, 3, 4, 5}; Void Display (List & v, const CHAR * S); int main () {list ilist; // Copy IaRray Backwards INTO ILIST COPY (IARRAY, IARRAY 5, Front_Insert); Display (IList, "Before Find and Copy"; / / LOCATE VALUE 3 in IList List :: item.egin (), ilist.end (), 3); // Copy First Two IaRay Values ​​to ilist ahead of popy (IaRray, IARRAY 2, INSERTER (ILIST, P)); Display (IList, "After Find and Copy"); Return 0;} Void Display (List & a, const char * s) {cout << s << Endl; Copy (a.begin (), a.end (), ostream_iterator (cout, ")); cout << Endl;} The results of the operation are as follows:

$ 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 ilist; list :: Iterator P = Find (IList.Begin (), IList.end (), 2); cout << "before: p ==" << * p << end1 Advance (p, 2); // Same AS P = P 2; cout << "after: p ==" << * P << endl; int K = 0; Distance (p, ilist.end (), k); cout << "k ==" << k << endl; advance () function accepts two parameters. The second parameter is the number of advanced advancement. For the front gear, this value must be positive, and the value can be negative for the two-way iterator and the random access iterator. Use the discance () function to return to the steps you need to reach another iterator. note

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 #include // Need random () > // NEED for_each () #define vsize 24 // size of vectorvector v (vsize); // vector object // function prototypesvoid initialize (long); void show (constling & ri); Bool Isminus (Const Long & ri); // Predicate Function Int Main () {Srandom (Time (NULL)); // seed random generator for_each (v.begin (), v.end (), initialize); // Call normal function COUT < <"Vector of Signed Long Integers << Endl; for_Each (v.begin (), v.end (), show); cout << endl; // use predicate function to count negative value // int count = 0; Vector p; p = find_if (v.begin (), v.end (), isminus); // call assembling function while (p! = v.end ()) {count ; p = find_if (p 1, v.end (), isminus;} cout << "Number of values:" << vsize << Endl; cout << "negative values:" << count << Endl; Return 0;} // set ri to a signed integer valuevoid ini TIALIZE (long & ri) {ri = (rand_max / 2)); // ri = random ();} // Display value of rivoid show (constling & ri) {cout << ri << " } // Returns True if ri is less 0bool isminus (const line & ri) {return (Ri <0);} The so-called assertion function is a function that returns the BOOL value. In addition to sending a callback function to the STL algorithm, you may also need to pass a class object to perform more complex operations. Such an object is called a function object. In fact, the function object is a class, but it can be called with the callback function. For example, statistics can be retained each time the function object is called by the for_each () or FIND_IF () function. Function objects are implemented by overloading Operator () () (). If TanyClass defines Opeator () (), you can use it:

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 must be included when using it.

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 #include // NEED Acumulate () # include // NEED Vector # incrude // NEED MULTIPLIES () (or timefine max 10Vector v (max); // vector Object int main () {// Fill Vector Using Conventional Loop // for (INT i = 0; i ()); // Note this line cout << "Product of values ​​==" << Product << Endl; Return 0;} Compile output is as follows:

$ 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 inline

_Ty accumulate (_ii _f, _ii _l, _ty _v)

{for (; _f! = _l; _ f)

_V = _v * _f;

Return (_V);} // template function Accumulate with binop

Template inline

_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 #include // need random () // NEED Vector # include // NEED PTR_FUN () Using Namespace Std; // Data To RandomizeInt IaRray [10] = {1, 2, 3, 4, 5, 6, 7, 8, 9 10}; Vector v (IaRray, IARRAY 10); // function prototypesvoid display (Vector & vr, const char * s); unsigned int randint; int main () {srandom (time (NULL)); // Seed random generator Display (v, "Before shuffle:"); pointer_to_unary_function ptr_RandInt = ptr_fun (randInt); // Pointer to randInt () // note This line random_shuffle (v.begin (), v.end (), ptr_randint); Display (v, "after shuffle:"); return 0;} // Display Contents of Vector Vrvoid Display (Vector & VR, Const char * s) {cout << Endl << S << Endl; Copy (vr.begin (), vr.end (), ostream_iterator (cout, ")); cout << endl;} / / Return next Random Value In SEQ Unce MODULO NUNSIGNED INT RANDINT (const unsigned int N) {return Random ()% n;} Compile operation results are as follows: $ g randfunc.cpp $ ./a.outbefore shuffle: 1 2 3 4 5 6 7 8 9 10AFTER shuffle: 6 7 2 8 3 5 10 1 9 4 First use the following statement to declare an object:

Pointer_to_unary_function PTR_RANDINT = PTR_FUN (RANDINT); This use STL's single-grade function template defines a variable PTR_Randint, and initializes the address to our function randint (). A single-grade function accepts a parameter and returns a value. Now Random_shuffle () can be called as follows:

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 #include // Need random_shuffle () # include // Need vector # include // Need unary_function using namespace std; // Data to randomizeint iarray [10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; Vector v (IARRAY, IARRAY 10); // Function Prototypevoid Display (Vector & VR, Const Char * s); // The Fiborand Template Function-Object ClassTemplate Class Fiborand: Public Unary_Function {INT I, J; Arg Sequence [18]; public: fiborand (); arg Operator () () Const arg & arg);}; void main () {FIBORAND fibogen; // construct generator object cout << "Fibonacci Random Number generator" << endl; cout << "using random_shuffle and a function object" << ENDL Display (V, "Before Shuffle:"); random_shuffle (v.begin (), v.end (), fibogen); Display (v, "after shuffle:");} // Display Contents of Vector Vrvoid Display Vector & vr, const char * s) {cout << Endl << S << endl; copy (vr.begin (), vr.end (), ostream_iterator ( Cout, "")); cout << Endl;} // fiborand class constructortemplate fiborand :: fiborand () {sequence [17] = 1; sequence [16] = 2; for (int N = 15; n> 0; n-) sequence [n] = sequence [n 1] sequence [n 2]; i = 17; j = 5;} // fiborand class function operatortemplate arg fiborand :: Operator () (const arg & arg) {arg k = sequence [i] sequence [j]; sequence [i] = k; i-; j--; if (i == 0) i = 17; if (j == 0) j = 17; Return K% arg;

} 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 Class Fiborand: Public Unary_Function {... arg is a user-defined data type. This class also sets two member functions, one is a constructor, and the other is an Operator () () function that allows the Random_shuffle () algorithm as "call" a Fiborand object like a function.

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 #include #include #include using namespace std; // DataINT IARRAY [10] = {1, 2, 3, 4, 5, 6, 7, 8 , 9, 10}; List Alist (IARRAY, IARRAY 10); int main () {INT K = 0; count_if (alist.begin (), alist.end (), bind1st (Greater ) ), 8), k); cout << "Number Elements <8 ==" << k << endl; return 0;} AlgorithM count_if () calculates the number of elements that meet specific conditions. This is implemented by bundling a function object and a parameter into an object, and the object is implemented as the third parameter of the algorithm. Pay attention to this expression:

Bind1st (Greater (), 8) This expression bundles greater () and a parameter value 8 into a function object. Since bind1st () is used, the function is equivalent to calculating the following expression:

8> Q The q expression is an object in the container. Therefore, complete expressions

Count_if (alist.egin (), alist.end (), bind1st (Greater (), 8), k); the number of objects that are less than or equal to 8 is calculated.

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 (), 8), k); if you want to search Q> 8 object, use bind2st. And now you can write this:

Start = find_if (alist.begin (), alist.end (), not1 (Bind1nd (Greater (), 6))); you must use NOT1 because bind1nd returns a single-optical function.

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.

转载请注明原文地址:https://www.9cbs.com/read-105562.html

New Post(0)