Article Title: STL Practice Guide Practical Guide To STL (on) Original Server: Jeff Bogan
Translator Note This is an article guided how you learn STL and practice in Microsoft Visual Studio. This article spoken from STL, step by step, gradually, involved in the method of STL writing code, STL code compilation, Namespace, ANSI / ISO string in STL, Various types In container, Template, Iterator, Algorithms, Allocator, container nested, etc., the author puts some suggestions in this article, and Point out the problem that should be noted when using STL. This article covers wide, and the perspective is comprehensive. It is not only suitable for beginners to learn STL, but also the practice guidelines for the readers using STL programming.
STL introduction
STL (Standard Template Library, Standard Template Library is a good technology that needs to master C programming today. I think everyone who first school STL should spend some time to familiarize it. For example, there will be a lot of learning curves in a sharp rise, and some name is not easy to remember, maybe I know. The name has been used in light), however, if you have a STL, you will not feel headache. STL is more complex and powerful than MFC. STL has some advantages:
You can easily achieve a series of algorithms such as search data or sort data sorting;
More secure and convenient when debugging procedures;
Even people who use STL in the UNIX platform you can easily understand (because STL is cross-platform).
background knowledge
Write this part is to let some beginner's readers have a good start in the challenging computer science field, not to understand the endless japanese terms and dull rules, just regarding those jars and rules here. STLER is used for self-entertainment creation.
The code used in this article is mainly guided in STL practices.
Some definitions of foundation concepts
Template - macro (Macro) of a class (and various data types and functions such as structures). Sometimes called a cookie cutter, a regular name should be called a generic - a class template called the generic class, and a function of a function is naturally called a modest function ( Generic function. STL - Standard Template Library, some of the intelligent people written some templates now have become part of the standard C language used by each person. Container - template class that can accommodate some data. There are versors such as VECTOR, SET, MAP, MULTIMAP and DEQUE in STL. Vector - Basic Array Template, which is a container. Cursor (Iterator) - This is a strange thing, it is a pointer to point to the elements in the STL container, or to other elements.
Hello World Program
I am willing to write my programs here: a Hello World program. This program transmits a string to a character vector and then displays one of the characters in the vector. The vector is like a garden that is growing, and half of all STL containers is based on the vector. If you have the program, you will almost master half the entire STL. // Program: Vector Demonstration One // Purpose: Understand the vector in STL
// #include "stdafx.h" - If you use the precompiled header file, you contain the header file of this header file #include
Char * szhw = "Hello World";
// This is an array of characters and ends with "/ 0".
INT Main (int Argc, char * argv []) {Vector
/ / Define a cursor Iterator for the character array. Vector
// Initialize the character vector, loop the entire string, // is used to fill the data into the character vector until "/ 0" is encountered. Char * cptr = szhw; // points a pointer to "Hello World" string while (* cptr! = '/ 0') {vec.push_back (* cptr); CPTR ;} // push_back function put data in vector The tail.
// Display the characters in the vector in the console for (vi = vec.begin (); vi! = Vec.end (); vi ) // This is the standardized start of the STL loop - usually " ! = ", Not" <"// because" <"is not defined in some containers. // begin () Returns the cursor of the vector starting element (Ite () returns the cursor (Iterator) of the vectors of the vector. {Cout << * vi;} // Use operator "*" to extract data from the cursor pointer. Cout << Endl; //
Return 0;}
Push_back is a standard function that puts data into a Vector (vector) or Deque (two-end queue). INSERT is a similar function, however it can be used in all containers, but usage is more complicated. End () is actually taking the end of the end (the previous elements at the end of the container) so that the loop is correctly run - it returns the pointer to the most close-to-array boundary. Just like an array in a normal cycle, such as for (i = 0; i <6; i ) {ar [i] = i;} --ar [6] does not exist, this element does not reach this element in the loop. Therefore, there will be no problem in the cycle.
One of the troubles of STL - initialization
STL is annoying place to initialize it. The initialization of the containers in the STL is more troublesome than that of the C / C array. You can only be an element, or first initialize a normal array and then fill in the container by transformation. I think people can usually do this:
// Program: Initialization Demo // Objective: To illustrate how the vector in STL is initialized. #include
INT Ar [10] = {12, 45, 234, 64, 12, 35, 63, 23, 12, 55}; char * str = "Hello World";
INT Main (int Argc, char * argv []) {Vector
In programming, there are many ways to complete the same job. Another way to fill the filler is to use more familiar square brackets, such as the following procedures:
// Program: Vector Demo 2 // Purpose: Understand the STL vector with array subscript and square brackets
#include
Char * SZHW = "Hello World"; int Main (int Argc, char * argv []) {Vector This example is clearer, but the operation of the cursor is less, and the additional shape is defined as the subscript, and you must clearly explain how much memory space is displayed in the program. Name space (Namespace) The concept related to STL is namespace. STL is defined in the STD namespace. There are three ways to declare the namespace used: 1. Use this namespace using this namespace, on the top of the file, but add: USING NAMESPACE STD; this method is the simplest method for a single project, this method can limit your code In the STD namespace. 2. Declaration of each object to be used before each template (just like originalization): use std :: cout; using std :: endl; using std :: flush; using std :: set; using std :: inserter Although there is a certain length of rotation, it can be more favorable for the function of memory usage, and you can easily declare and use members in other namespaces. 3. Using the STD domain identifier when using the template in the STD namespace. For example: typedef std :: Vector Vec_Str; this method thoughs are relatively long, but is the best way to mix the use of multiple namespaces. Some STL's fanatics have been using this method and regard those who do not use this method as a heterogeneous. Some people will build some macro simplified issues through this approach. In addition, you can add Using Namespace STD to any domain, such as the head or a control cycler of the function. some advices To avoid annoying warnings in debug mode, use the following compiler command: #pragma Warning (Disable: 4786) Another thing to note is that you must ensure that there is a space between two angle brackets or between the angle brackets and the name, because it is to avoid confusion with the ">>" shift operator. For example, Vector> Veclis; this will write error, and write this: Vector> Veclis; you can avoid errors. Article title: STL Practice Guide Practical Guide to STL (middle) Original author: Jeff Bogan (Connected) Another container - set (SET) This is the interpretation of the Collection (SET) in Microsoft Help document: "Describes an object that controls the sequence of germplasses (Note: Key and Value in the set are key types, while Key and Value in Map are a PAIR structure Two components of the medium), each element contains a sort key and a value (Value). You can find, insert, and delete any of the elements in any element in the sequence, and complete these operations The time is a proportional relationship with the number of elements in this sequence, and when the binder points to a deleted element, the delete operation is invalid. "And a corrected and more actual definition should be: a collection (SET) Is a container, which is unique in which the elements contained therein are unique. This is useful when collecting a specific value of a data. The elements in the collection are arranged in a certain order and are used as an example in the collection. If you need a key / value pair (PAIR) to store data, MAP is a better choice. A collection is organized through a linked list, which is slower than the vector (Vector), but finds or adds the end of the elements. Below is an example: // Program: SET Demo // Purpose: Understand the collection of STL (SET) #include Int main (int Argc, char * argv []) {set If you are interested, you can replace the output loop with the following code: Copy (strSet.egin (), strset.end (), ostream_iterator Although the collection (SET) is more powerful, I personally think that it is unclear, and it is easier to make mistakes. If you understand this, you will know what to do with a collection (SET). All STL containers The concept of container is earlier than template, which is originally an important concept in a computer science field, but here, its concept is mixed with STL. Here is the 7 containers that appear in STL: VECTOR (vector) - A secure array in STL. Can only add data in the "front" of the Vector. DEQUE (Double-end queue double-ended queue) - is similar to the vector, but data can be added to the front and rear ends. List (list) - The cursor can only be moved at a time. If you are already familiar with the list, then the LIST in the STL is a two-way linked list (each node has two pointers that are forwarded and pointing to the successive subsequent). Set (Collection) - contains sorted data, which must be unique. Map (mapping) -Rolded binary groups, each element in MAP consists of two values, where the key (key value, key value in a map must be unique) Use when sorting or searching, it can be re-acquired in the container; and the other value is the value associated with the element. For example, in addition to the AR [43] = "Overripe" finds a data, the MAP can also find a data via Ar [Banana "] =" Overripe ". If you want to get the element information, you can easily implement the full name of the input element. MultiSet - and Collection (SET) are similar, but the values are not required to be unique (ie, repetition). MultiMap - and Mapp (MAP) are similar, however, the key value is not required (that is, you can have repetition). Note: If you read Microsoft's help documentation, you will encounter a statement on the efficiency of each container. For example: LOG (N * n) insertion time. The impact of these times can be ignored unless you have to handle a lot of data. If you find that your program has obvious hysteresis or requires time critical things, you can learn more about various container operational efficiency. How to use classes in a map? MAP is a template class that gets value (value) through the Key. Another problem is that you want to use your own classes in Map, not existing data types, such as INT that has been used now. Create a "Template-Ready" class, you must ensure that some member functions and overload operators are included in this class. Some members of the following are must: Default constructor (usually empty) Copy constructor Overloaded "=" operator You should overload as many operators as possible to meet the needs of a particular template, for example, if you want to define a key (key) in the MAP, you must overload the relevant operator. But there is no discussion of overload operators here. // Program: Map the custom class. // Objective: Describe how to use custom classes in MAP. #include Class cstudent {public: int nStudentId; int nage; public: // Default constructor - usually empty cstudent () {} // complete constructor cstudent (int nsid, int NA) {nStudentId = nsid; NAGE = Na;} // copy constructor cstudent (const cstract & ob) {nStudentId = ob.nstudentID; Nage = ob.nage;} // Reserved "=" void operator = (const cstudent & ob) {nstudentId = ob.nstudentId; Nage = ob.nage;}}; int main (int Argc, char * argv []) {Map MapStudent ["Joe Lennon"] = CSTUDENT (103547, 22); MapStudent ["Phil McCartney"] = CStudent (100723, 22); MapStudent ["Raoul Starr"] = CStudent (107350, 24); Mapstudent ["Gordon Hamilton "] = CStudent (102330, 22); // Visit the member COUT << "The Student Number for Joe Lennon IS" in the CStudent class by name "(MapStudent [Joe Lennon"]. NstudentId << Endl Return 0;} Typedef If you like to use the typedef keyword, the following is an example: typedef set A habit of writing code is to use uppercase letters and underscores to name data types. ANSI / ISO string The ANSI / ISO string is used very common in the STL container. This is a standard string class and has been widely advocated, but problems will be issued in the absence of format declaration. You must use the "<<" and input and output streams (such as DEC, Width, etc.) to link the string. The character pointer can be re-obtained using c_str () when necessary. Article title: STL Practice Guide Practical Guide to STL (below) Original Server: Jeff Bogan (Connected) Iterator I said that the cursor is a pointer, but it is not just a pointer. The cursors and pointers are very similar, and the functions are very like pointers, but in fact, the cursor returns a value from the container in the container. Store these values in the container is not a good idea, because every new value is added to the container or has a value deleted from the container, these values will be invalid. To a certain extent, the cursor can be regarded as a handle (HANDLE). Normally, the type of ITATOR can vary, so that the container will also have several different ways: Iterator - For any other container other than the Vector, you can use this cursor in a container in a container Take a step in the direction of the front. This means that you can only use the " " operator for this kind of cursor. And you can't use the "-" or " =" operator. For the container of Vector, you can use " =", "-", " ", "=", and "<", "<=", ">", Comparison operators such as "> =", "==", "! =". Reverse_iterator - If you want to use the coming direction instead of the forward direction, you can traverse the elements in the container outside the vector, you can use the reverse_iterator to reverse the direction of traversal, you can also use rbegin () Instead of begin (), replace end (), while the " " operator is traversed in the direction behind. Const_iterator - a cursor in forward direction that returns a constant value. You can use this type of cursor to point to a read-only value. Const_reverse_iterator - a cursor traversed in the opposite direction that returns a constant value. Sort in Set and Map In addition to type and value, templates contain other parameters. You can pass a callback function (usually the statement "predicate" - this is a function with a parameter returns a Boolean value). For example, if you want to automatically create a collection, the elements in the collection are arranged in ascending order, you can build a set class with a concise method: Set Greater is another template function (norm function) that is used to sort these values when the value is placed in the container. If you want to arrange these values in descending, you can write this: Set When implementing an algorithm, a lot of situations are passed as a parameter into a STL template class, and these situations will be described in detail below. STL's troubles - Error information Names of these templates need to be expanded to the compiler, so when the compiler fails, it will list a long error message, and these error messages are difficult to understand. I don't think there is a good way to deal with this problem. But the best way is to find and carefully study the end of the code segment. Another trouble is: When you double-click the error message, it will correct the internal code of the template library, and these code is more difficult to read. Under normal circumstances, the best way to correct the correctment is to re-check your code and ignore all warning messages when running. Algorithms The algorithm is a function used in the template. This really begins to reflect the power of STL. You can learn some of the algorithms that can be used in most template containers so you can sort, find, exchange, etc. in the easiest way. The STL contains a series of functions of a series of implementation algorithms. For example: sort (vec.begin () 1, vec.end () - 1) enables the ordering operation of other elements of the first and last elements. The container itself cannot use an algorithm, but the cursor in the two containers can define an element using algorithm in the container. In this case, the algorithm is not directly limited by the container, but by using a cursor, the algorithm can be supported. In addition, many times you will encounter a function that is ready (previously mentioned: Predicate) as a parameter, you can also pass the previous old value. The following example demonstrates how to use algorithms: // Program: Test score statistics // purpose: How to use algorithm by operating the score saved in the vector #include INT testscore [] = {67, 56, 24, 78, 99, 87, 56}; / / Judging whether a grade passes the test bool passed_test (int N) {return (n> = 60); / / Judge whether a grade does not have a BOOL FAILED_TEST (INT N) {Return (N <60); INT Main (int ) {int total; // Initialization vector, enable it to load the elements in the TestScore array Vector // Sort and display the data in the vector sort (vectestscore.begin (), vectestscore.end ()); cout << "sorted test score: << Endl; for (vi = vectestscore.begin (); vi! = VECTESTSCORE.END (); vi ) {cout << * vi << ",";} cout << endl; // Display statistics // min_element returns a _iterator_ type object that points the minimum value of the value. // "*" operator extracts the value in the element. Vi = min_egin (), vectestscore.end ()); cout << "The lowest score was" << * vi << "." << endl; // Similar to Min_Element, MAX_ELEMENT is the maximum value. Vi = max_element (vectestscore.egin (), vectestscore.end ()); cout << "The higherst score was" << * vi << "." << endl; // use a declaration function (Predicate function, referring to VECTESTSCORE .begin () and vectestscore.end ()) to determine the number of people through the exam. Cout << count_if (vectestscore.begin (), vectestscore.end (), passed_test) << "out of" << vectestscore.size () << "students passed the test" << Endl; / / Determine how many people exam hung COUT << count_if (vectestscore.begin (), vectestscore.end (), failed_test) << "out of" << vectestscore.size () "students failed the test" // Calculate the sum of grades Total = Accum (), vectestscore.egin (), vectestscore.egin (), 0); // calculate the average grade COUT << "Average Score WAS" << (Total / (INT) (vectestscore.size ())) << ENDL; Return 0;} ALLOCATOR Allocator is used in the initial phase of the template, which is a template class that assigns memory space and release space operations for objects and arrays. It plays a very mysterious role in a variety of situations, which is concerned about the optimization of high-level memory, and for black box testing, using allocator is the best choice. Typically, we don't need to specify it because they are usually arguable as the default parameters that do not have to be added. If Allocator appears in a professional test, you'd better understand what it is. Embed Templates and Derive Templates (Base Template) Whenever you use an ordinary class, you can also use a STL class in it. It can be embedded: Class CParam {string name; string unit; vector Or use it as a base class: Class CParam: Public Vector The STL template class needs to be cautious as the base class. This requires you to adapt to this programming. Template in the template To build a complex data structure, you can implant a template into another template (ie "template nested"). The general method is to define a template type using the TypeDef keyword in front of the program. // Program: Demo in the vector in vector. // Objective: To explain how to use nested STL containers. #include Typedef vector INT INP [2] [2] = {{1, 1}, {2, 0}}; // To put the regular array of 2x2 in the template INT Main (int Argc, char * argv []) {Int i, j; vector 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 when initialization, once you bring the data, you will have a long expandable two-dimensional array (size can be expanded until the memory is used). Depending on the actual needs, nested combinations of various containers can be used. to sum up STL is useful, but difficulties and trouble during use are inevitable. Just like the Chinese said: "If you master it, it is like a tiger to add." Related Links: Josuttis Website: http://www.josuttis.com/ Pretty Good Initialization Library: http://www.codeproject.com/vcpp/stl/pgil.asp (Full text)