STL Practice Guide Practical Guide to STL
Author: Jeff bogan
Translation: Zhou Xiang
(Part 2)
Cursor (iterator)
I have said that a cursor is a pointer, but not just a pointer. A cursor is similar to a pointer, and its function is similar to a pointer. However, a cursor returns a value from the center of the container by reloading the "*" and "->" of a dollar. It is not a good idea to store these values in the container, because these values will become invalid whenever a new value is added to the container or a value is deleted from the container. To some extent, a cursor can be seen as a handle ). Generally, the type of the cursor (iterator) can be changed, so the container has several different ways of Transformation:
Iterator --For any container except the vector, you can use this cursor to take a step forward to the container in one operation. This means that you can only use the "++" Operator for such cursors. You cannot use the "--" or "+ =" operators. For the vector container, you can use any operator in "+ =", "-", "+ +", "-=", and "<", "<=", "> ", "> =", "=", "! = "And other comparison operators.
Reverse_iterator --If you want to use a cursor in the backward direction instead of the forward direction to traverse elements in containers other than the vector, you can use reverse_iterator to reverse the traversal direction. You can also use rbegin () in place of begin (), replace end () with rend (), and then the "++" operator will traverse in the backward direction.
Const_iterator --A forward cursor that returns a constant value. You can use this type of cursor to point to a read-only value.
Const_reverse_iterator --A cursor that traverses in the opposite direction. It returns a constant value.
Sorting in set and map
In addition to the type and value, the template contains other parameters. You can pass a callback function (usually the Declaration "predicate" -- this is a function with a parameter that returns a Boolean value ). For example, if you want to automatically create a set and the elements in the set are arranged in ascending order, you can use a concise method to create a set class:
Set <int, greater <int> set1
Greater Is another template function (model function), which is used to sort these values after the value is placed in the container. If you want to sort these values in descending order, you can write as follows:
Set <int, less <int> set1
When the algorithm is implemented, when the Declaration (predicate) is passed to an STL template class as a parameter, many other situations are encountered. The following describes these situations in detail.
STL troubles 2-error message
These templates need to be extended to the compiler, so when the compiler fails for some reason, it will list a long piece of error information that is obscure. I think there is no good way to deal with such problems. But the best way is to find and carefully study the error information to specify the end of the code segment. Another headache is that when you double-click the error message, it points the error to the internal code of the template library, and the code is more difficult to read. In general, the best way to correct errors is to re-check your code and ignore all warning information during runtime.
Algorithm (algorithms)
An algorithm is a function used in a template. This truly begins to reflect the power of STL. You can learn some Algorithm functions that are used in most template containers, so that you can sort, search, exchange, and perform other operations in the simplest way. STL contains a series of functions that implement algorithms. For example, sort (VEC. Begin () + 1, VEC. End ()-1) can sort other elements except the first and last elements.
The container itself cannot use algorithms, but the cursors in the two containers can limit the elements of the Algorithm Used in the container. In this case, the algorithm is not directly restricted by the container, but is supported by using a cursor. In addition, many times you will encounter passing a ready function (previously mentioned declaration: predicate) as the parameter, you can also pass the old value.
The following example demonstrates how to use an algorithm:
// Program: test score statistics
// Purpose: to explain how to use the algorithm by performing operations on the scores saved in the vector
# Include<Algorithm> // to use Algorithm functions, you must include this header file.
# Include <numeric> // header file containing the accumulate (SUM) Function
# Include <vector>
# Include <iostream>
Using namespace STD;
Int testscore [] = {67, 56, 24, 78, 99, 87, 56 };
// Determine whether a score has passed the test
Bool passed_test (int n)
{
Return (n> = 60 );
}
// Judge whether a score fails
Bool failed_test (int n)
{
Return (n <60 );
}
Int main (INT argc, char * argv [])
{
Int total;
// Initialize the vector to load the elements in the testscore array.
Vector <int> vectestscore (testscore,
Testscore + sizeof (testscore)/sizeof (INT ));
Vector <int>: iterator VI;
// Sort and display the data in the vector
Sort (vectestscore. Begin (), vectestscore. End ());
Cout <"sorted test scores:" <Endl;
For (Vi = vectestscore. Begin (); vi! = Vectestscore. End (); vi ++)
{Cout <* VI <",";}
Cout <Endl;
// Display statistics
// Min_element returns a _ iterator _ type object pointing to the element with the smallest value.
// The "*" operator extracts the value from the element.
Vi = min_element (vectestscore. Begin (), vectestscore. End ());
Cout <"the lowest score was" <* VI <"." <Endl;
// Similar to min_element, max_element selects the maximum value.
Vi = max_element (vectestscore. Begin (), vectestscore. End ());
Cout <"the highest score was" <* VI <"." <Endl;
// Use the predicate function (vectestscore. Begin () and vectestscore. End () to determine the number of people passing the test.
Cout <count_if (vectestscore. Begin (), vectestscore. End (), passed_test) <
"Out of" <vectestscore. Size () <
"Students passed the test" <Endl;
// Determine the number of students who failed the exam
Cout <count_if (vectestscore. Begin (),
Vectestscore. End (), failed_test) <
"Out of" <vectestscore. Size () <
"Students failed the test" <Endl;
// Calculate the total score
Total = accumulate (vectestscore. Begin (),
Vectestscore. End (), 0 );
// Calculate and display the average score
Cout <"average score was" <
(Total/(INT) (vectestscore. Size () <Endl;
Return 0;
}
Allocator (distributor)
Allocator is used in the template initialization stage. It is a template class for allocating and releasing memory space for objects and arrays. It plays a mysterious role in various situations. It is concerned with the optimization of high-level memory, and the use of allocator is the best choice for black box testing. Generally, we do not need to specify it explicitly because they are usually used as default parameters that do not need to be added. If Allocator occurs in professional testing, you 'd better figure out what it is.
Embed templates (embedded template) and derive templates (base template)
Whenever you use a common class, you can also use an STL class. It can be embedded:
Class cparam
{
String name;
String unit;
Vector <double> vecdata;
};
Or use it as a base class:
Class cparam: Public vector <double>
{
String name;
String unit;
};
Exercise caution when using the STL template class as the base class. This requires you to adapt to this programming method.
Template in the template
To build a complex data structure, you can implant one template into another (that is, "template nesting "). Generally, the best method is to use the typedef keyword before the program to define the template type used in another template.
// Program: Demonstration of embedding a vector in a vector.
// Purpose: to explain how to use nested STL containers.
# Include <iostream>
# Include <vector>
Using namespace STD;
Typedef vector <int> vec_int;
Int indium [2] [2] = {1, 1}, {2, 0 }};
// The 2x2 regular array to be put into the Template
Int main (INT argc, char * argv [])
{
Int I, J;
Vector <vec_int> vecvec;
// If You Want To implement such nesting in one sentence, you can write as follows:
// Vector <int> vecvec;
// Input the array into the vector
Vec_int V0 (indium [0], indium [0] + 2 );
// Pass two pointers
// Copy the values in the array to the vector.
Vec_int V1 (indium [1], indium [1] + 2 );
Vecvec. push_back (v0 );
Vecvec. push_back (V1 );
For (I = 0; I <2; I ++)
{
For (j = 0; j <2; j ++)
{
Cout <vecvec [I] [J] <"";
}
Cout <Endl;
}
Return 0;
}
// Output:
// 1 1
// 2 0
Although it is troublesome during initialization, once you fill in the data as a vector, you will implement a variable-length, extensible two-dimensional array (the size can be expanded until the memory is used up ). You can use nested combinations of various containers as needed.
Summary
STL is useful, but the difficulties and troubles in the use process are inevitable. As the Chinese said: "If you master it, it will be even more powerful ."
Related links:
Josutis Website: http://www.josuttis.com/
Pretty good initialization Library: http://www.codeproject.com/vcpp/stl/PGIL.asp