The map is a template that uses a key to obtain a value. Another issue is that you will want to use your own classes instead of data types, like int that has been used up to now. To create a class that is "template-ready", you must be ensure that the class contains certain member functions and operators. The basics are: * default constructor (empty, usually) * copy constructor * overload "=" You would overload more operators as required in a specific template, for example, if you plan to have a class that is a key in a map you would have to overload relational operators. But that is another story. // Program: Map Own Class // Purpose: To demonstrate a map of classes #include #include #include #include class CStudent { public : int nStudentID; int nAge; public : // Default Constructor - Empty CStudent() { } // Full constructor CStudent(int nSID, int nA) { nStudentID=nSID; nAge=nA; } // Copy constructor CStudent(const CStudent& ob) { nStudentID=ob.nStudentID; nAge=ob.nAge; } // Overload = void operator = (const CStudent& ob) { nStudentID=ob.nStudentID; nAge=ob.nAge; } }; int main(int argc, char* argv[]) { map <string, CStudent> mapStudent; mapStudent["Joe Lennon"] = CStudent(103547, 22); mapStudent["Phil McCartney?"] = CStudent(100723, 22); mapStudent["Raoul Starr"] = CStudent(107350, 24); mapStudent["Gordon Hamilton"] = CStudent(102330, 22); // Access via the name cout << "The Student number for Joe Lennon is " << (mapStudent["Joe Lennon"].nStudentID) << endl; return 0; } TYPEDEF If you like to use typedef, this an example: typedef set SET_INT; typedef SET_INT::iterator SET_INT_ITER One convention is to make them upper case with underscores. ANSI / ISO string ANSI/ISO strings are commonly used within STL containers. It is your standard string class, widely praised except for its deficiency of no format statement. You must instead use << and the iostream codes (dec, width, etc.) to string together your string. Use c_str() to retrieve a character pointer, when necessary. Iterators I said that iterators are pointers, but there is more. They look like pointers, act like pointers, but they are actually embedded in which the indirection operator (unary *) and -> have been overloaded to return a value from the container. It is a bad idea to store them for any length of time, as they usually invalid after a value has been added or removed from a container. They are something like handles in this regard. The plain iterator can be altered, so that the container is to be traversed in different ways: * iterator - For any container other than the vector, you can only step one at a time in a forward direction through the container. That is you can only use the ++ operator, not the -- or += operator on it. For vector only you can use any of +=, --, -=, ++, and all the comparison operators <, <=, >, >=, =, . * reverse_iterator - If you want to step backwards instead of forwards through a non-vector container, replace iterator with reverse_iterator, begin() with rbegin(), and end() with rend(), ++ will then traverse backwards. * const_iterator - a forward iterator that returns a const value. Use this if you want to make it clear that this points to a read-only value. * const_reverse_iterator - a reverse iterator that returns a const value. Sorting Order in Sets and Maps Templates have other parameters besides the type of value. You can also pass callback functions (known as predicates - this is a function of one argument that returns a bool value). For example, say you want a set of strings that are automatically sorting in ascending order. You would simply create a set class in this way: set <int, greater > set1 greater is another template for a function (generic function) which is used to sort values, as they are placed into the container. If you wanted the set to be sorted in descending order, you would write: set <int, less > set1 There are many other cased you must pass a predicate as parameter to the STL class, in algorithms, described below. STL Annoyance #2 - Long Error Messages The templated names get expanded for the compiler, so when the compiler chokes on something, it spits out extremely long error messages that are difficult to read. I have found no good way around this. The best is to develop the ability to find and focus on the end of the error code where the explanation is located. Another related annoyance: if you double click on the template error, it will take you to the point in the code within the template code, which is also difficult to read. Sometimes, it is best just to carefully re-examine your code, and ignore the error messages completely. Algorithms Algorithms are functions that apply to templates. This is where the real power of STL starts to show up. You can learn a few function names that usually apply to most of the template containers. You can sort, search, manipulate, and swap with the greatest of ease. They always contain a range within which the algorithm performs. E.g.: sort(vec.begin()+1, vec.end()-1) sorts everything but the first and last values. The container itself is not passed to the algorithm, just two iterators from the container that bookend a range. In this way, algorithms are not restricted by containers directly, but by the iterators supported by that specific algorithm. In addition, many times you will also pass a name of a specially prepared function (those afore mentioned predicates) as an argument. You can even pass plain old values. |