C++ Template Library Module28 Tenouk
C++ Template Library Module28 Tenouk
--THE STL--
CONTAINER PART II
list, set, multiset
Note: Compiled using VC++7.0/.Net, win32 empty console mode application. g++ program compilation examples
given at the end of this Module.
Abilities
28.1 Lists
- A list is implemented as a doubly linked list of elements. This means each element in a list has its own
segment of memory and refers to its predecessor and its successor.
- Lists do not provide random access. It can be depicted as follow:
- For example, to access the tenth element, you must navigate the first nine elements by following the
chain of their links. However, a step to the next or previous element is possible in constant time.
- Thus, the general access to an arbitrary element takes linear time (the average distance is proportional
to the number of elements). This is a lot worse than the amortized constant time provided by vectors
and deques.
- The advantage of a list is that the insertion or removal of an element is fast at any position. Only the
links must be changed. This implies that moving an element in the middle of a list is very fast
compared with moving an element in a vector or a deque.
- The list member functions merge(), reverse(), unique(), remove(), and remove_if()
have been optimized for operation on list objects and offer a high-performance alternative to their
generic counterparts.
- List reallocation occurs when a member function must insert or erase elements of the list. In all such
cases, only iterators or references that point at erased portions of the controlled sequence become
invalid.
- The following general list example creates an empty list of characters, inserts all characters from 'a' to
'z', and prints all elements by using a loop that actually prints and removes the first element of the
collection:
//list example
#include <iostream>
#include <list>
using namespace std;
int main()
{
//list container for character elements
list<char> elem;
www.tenouk.com Page 1 of 29
return 0;
}
Output:
- With STL, using loop to print the outputs and removes the element is not a proper way. Normally, we
would iterate over all elements using iterator. Using loop in the program example just for discussion.
- However, direct element access by using operator[] is not provided for lists. This is because lists
don't provide random access, and thus using operator[] would cause bad performance.
- There is another way to loop over the elements and print them by using iterators.
Operators
Operator Description
Tests if the list object on the left side of the operator is not equal to the list object on the
operator!=
right side.
Tests if the list object on the left side of the operator is less than the list object on the
operator<
right side.
Tests if the list object on the left side of the operator is less than or equal to the list
operator<=
object on the right side.
Tests if the list object on the left side of the operator is equal to the list object on the
operator==
right side.
Tests if the list object on the left side of the operator is greater than the list object on the
operator>
right side.
Tests if the list object on the left side of the operator is greater than or equal to the list
operator>=
object on the right side.
Table 28.1
Class Description
A template class of sequence containers that maintain their elements in a linear
list
arrangement and allow efficient insertions and deletions at any location within the
Class
sequence.
table 28.2
- The STL list class is a template class of sequence containers that maintain their elements in a linear
arrangement and allow efficient insertions and deletions at any location within the sequence.
- The sequence is stored as a bidirectional linked list of elements, each containing a member of some
type Type.
Typedefs
Typedef Description
allocator_type A type that represents the allocator class for a list object.
A type that provides a bidirectional iterator that can read a const
const_iterator
element in a list.
const_pointer A type that provides a pointer to a const element in a list.
A type that provides a reference to a const element stored in a list for
const_reference
reading and performing const operations.
A type that provides a bidirectional iterator that can read any const
const_reverse_iterator
element in a list.
difference_type A type that provides the difference between two iterators those refer to
www.tenouk.com Page 2 of 29
elements within the same list.
A type that provides a bidirectional iterator that can read or modify any
iterator
element in a list.
pointer A type that provides a pointer to an element in a list.
A type that provides a reference to a const element stored in a list for
reference
reading and performing const operations.
A type that provides a bidirectional iterator that can read or modify an
reverse_iterator
element in a reversed list.
size_type A type that counts the number of elements in a list.
value_type A type that represents the data type stored in a list.
Table 28.3
Table 28.4
- list constructor, constructs a list of a specific size or with elements of a specific value or with a specific
allocator or as a copy of all or part of some other list.
- All constructors store an allocator object and initialize the list.
- get_allocator() returns a copy of the allocator object used to construct a list.
- None of the constructors perform any interim reallocations.
//list constructors
#include <list>
#include <iostream>
using namespace std;
www.tenouk.com Page 3 of 29
int main()
{
list <int>::iterator li0Iter, li1Iter, li2Iter, li3Iter, li4Iter, li5Iter, li6Iter;
//Create a list li6 by copying the range of li4[_First, _Last) and with
//the allocator of list li2
li4Iter = li4.begin();
li4Iter++;
li4Iter++;
li4Iter++;
list <int> li6(li4.begin(), li4Iter, li2.get_allocator());
//----------------------------------------------------
cout<<"Operation: list <int> li0\n";
cout<<"li0 data: ";
for(li0Iter = li0.begin(); li0Iter != li0.end(); li0Iter++)
cout<<" "<<*li0Iter;
cout<<endl;
www.tenouk.com Page 4 of 29
cout<<endl;
return 0;
}
Output:
- The return value is the first insert() function returns an iterator that point to the position where the
new element was inserted into the list.
- Any insertion operation can be expensive in term of time and resource.
//list, insert()
#include <list>
#include <iostream>
using namespace std;
int main()
{
list <int> lis1, lis2;
list <int>::iterator Iter;
lis1.push_back(13);
lis1.push_back(22);
lis1.push_back(15);
lis2.push_back(9);
lis2.push_back(5);
lis2.push_back(45);
www.tenouk.com Page 5 of 29
Iter = lis1.begin();
Iter++;
Iter++;
lis1.insert(Iter, 3, 30);
cout<<"\nOperation2: lis1.insert(++lis1.begin(),\n"
" lis2.begin(),--lis2.end())\n";
lis1.insert(++lis1.begin(), lis2.begin(),--lis2.end());
cout<<"lis1 data: ";
for(Iter = lis1.begin(); Iter != lis1.end(); Iter++)
cout<<" "<<*Iter;
cout<<endl;
return 0;
}
Output:
//list, remove()
#include <list>
#include <iostream>
using namespace std;
int main( )
{
list <int> lis1;
list <int>::iterator lis1Iter, lis2Iter;
lis1.push_back(7);
lis1.push_back(12);
lis1.push_back(25);
lis1.push_back(7);
lis1.push_back(9);
lis1.push_back(7);
lis1.push_back(21);
www.tenouk.com Page 6 of 29
Output:
- The first member function puts the elements in ascending order by default.
- The member template function orders the elements according to the user-specified comparison
operation _Comp of class Traits.
//list, sort()
#include <list>
#include <iostream>
using namespace std;
int main()
{
list <int> ls1;
list <int>::iterator ls1Iter;
ls1.push_back(31);
ls1.push_back(12);
ls1.push_back(40);
ls1.push_back(15);
ls1.push_back(9);
ls1.push_back(44);
cout<<"\nOperation: ls1.sort()\n";
ls1.sort();
cout<<"After sorting, ls1 data: ";
for(ls1Iter = ls1.begin(); ls1Iter != ls1.end(); ls1Iter++)
cout<<" "<<*ls1Iter;
cout<<endl;
cout<<"\nOperation: ls1.sort(greater<int>())\n";
ls1.sort(greater<int>());
cout<<"Re sort with 'greater than' operation,\nls1 =";
for(ls1Iter = ls1.begin(); ls1Iter != ls1.end(); ls1Iter++)
cout<<" "<<*ls1Iter;
cout<<endl;
return 0;
}
Output:
//list, splice()
#include <list>
#include <iostream>
using namespace std;
www.tenouk.com Page 7 of 29
int main( )
{
list <int> ls1, ls2, ls3, ls4;
list <int>::iterator ls1Iter, ls2Iter, ls3Iter, ls4Iter, PIter, QIter, RIter;
ls1.push_back(7);
ls1.push_back(15);
ls2.push_back(9);
ls2.push_back(22);
ls2.push_back(12);
ls3.push_back(29);
ls3.push_back(30);
ls4.push_back(33);
ls4.push_back(25);
ls4.push_back(51);
Output:
www.tenouk.com Page 8 of 29
- This function assumes that the list is sorted, so that all duplicate elements are adjacent. Duplicates that
are not adjacent will not be deleted.
- The first member function removes every element that compares equal to its preceding element.
- The second member function removes every element that satisfies the predicate function when
compared with its preceding element.
//list, unique()
#include <list>
#include <iostream>
using namespace std;
int main()
{
list <int> ls1;
list <int>::iterator ls1Iter, ls2Iter, ls3Iter;
not_equal_to<int> mypred;
ls1.push_back(-12);
ls1.push_back(12);
ls1.push_back(12);
ls1.push_back(22);
ls1.push_back(22);
ls1.push_back(13);
ls1.push_back(-12);
ls1.push_back(14);
Output:
www.tenouk.com Page 9 of 29
---------------------------------------------------End of list---------------------------------------------
---www.tenouk.com---
- Associative containers sort their elements automatically according to a certain ordering criterion.
- This criterion takes the form of a function that compares either the value or a special key that is
defined for the value.
- By default, the containers compare the elements or the keys with operator less than (<). However, you
can supply your own comparison function to define another ordering criterion.
- Associative containers are typically implemented as binary trees. Thus, every element (every node)
has one parent and two children. All ancestors to the left have lesser values; all ancestors to the right
have greater values. It can be depicted as follow:
- The associative containers differ in the kind of elements they support and how they handle
duplicates. The following is discussion of the associative containers that are predefined in the STL.
- All of the associative container classes have an optional template argument for the sorting criterion.
The default sorting criterion is the operator < (les than).
- The sorting criterion is also used as the test for equality; that is, two elements are equal if neither is less
than the other.
- You can consider a set as a special kind of map, in which the value is identical to the key. In fact, all of
these associative container types are usually implemented by using the same basic implementation of a
binary tree.
- The choice of container type should be based in general on the type of searching and inserting required
by the application.
- Associative containers are optimized for the operations of lookup, insertion and removal. The member
functions that explicitly support these operations are efficient, performing them in a time that is on
average proportional to the logarithm of the number of elements in the container.
- Inserting elements invalidates no iterators, and removing elements invalidates only those iterators that
had specifically pointed at the removed elements.
www.tenouk.com Page 10 of 29
28.4 Sets
- A set is a collection in which elements are sorted according to their own values. Each element may
occur only once, thus duplicates are not allowed. Its structure can be depicted as shown below.
Operators
Operator Description
Tests if the set or multiset object on the left side of the operator is not equal to the
operator!=
set or multiset object on the right side.
Tests if the set or multiset object on the left side of the operator is less than the set
operator<
or multiset object on the right side.
Tests if the set or multiset object on the left side of the operator is less than or equal
operator<=
to the set or multiset object on the right side.
Tests if the set or multiset object on the left side of the operator is equal to the set
operator==
or multiset object on the right side.
Tests if the set or multiset object on the left side of the operator is greater than the
operator>
set or multiset object on the right side.
Tests if the set or multiset object on the left side of the operator is greater than or
operator>=
equal to the set or multiset object on the right side.
Table 28.5
Specialized
template Description
function
swap() Exchanges the elements of two sets or multisets.
Table 28.6
Class Description
Used for the storage and retrieval of data from a collection in which the values of
set Class the elements contained are unique and serve as the key values according to which
the data is automatically ordered.
Used for the storage and retrieval of data from a collection in which the values of
multiset
the elements contained need not be unique and in which they serve as the key
Class
values according to which the data is automatically ordered.
Table 28.7
Typedefs
Typedef Description
allocator_type A type that represents the allocator class for the set object.
A type that provides a bidirectional iterator that can read a const element
const_iterator
in the set.
const_pointer A type that provides a pointer to a const element in a set.
www.tenouk.com Page 11 of 29
A type that provides a reference to a const element stored in a set for
const_reference
reading and performing const operations.
A type that provides a bidirectional iterator that can read any const
const_reverse_iterator
element in the set.
A signed integer type that can be used to represent the number of elements
difference_type
of a set in a range between elements pointed to by iterators.
A type that provides a bidirectional iterator that can read or modify any
iterator
element in a set.
A type that provides a function object that can compare two sort keys to
key_compare
determine the relative order of two elements in the set.
The type describes an object stored as an element of a set in its capacity as
key_type
sort key.
pointer A type that provides a pointer to an element in a set.
reference A type that provides a reference to an element stored in a set.
A type that provides a bidirectional iterator that can read or modify an
reverse_iterator
element in a reversed set.
An unsigned integer type that can represent the number of elements in a
size_type
set.
The type that provides a function object that can compare two elements to
value_compare
determine their relative order in the set.
The type describes an object stored as an element of a set in its capacity as
value_type
a value.
Table 28.8
Table 28.9
- The STL container class set is used for the storage and retrieval of data from a collection in which the
values of the elements contained are unique and serve as the key values according to which the data is
automatically ordered.
www.tenouk.com Page 12 of 29
- The value of an element in a set may not be changed directly. Instead, you must delete old values and
insert elements with new values.
template <
class Key,
class Traits = less<Key>,
class Allocator = allocator<Key>
>
Parameters
Parameter Description
Key The element data type to be stored in the set.
The type that provides a function object that can compare two element values as sort keys to
Traits
determine their relative order in the set. This argument is optional, and the binary predicate
less <Key> is the default value.
The type that represents the stored allocator object that encapsulates details about the set's
Allocator
allocation and de-allocation of memory. This argument is optional, and the default value is
allocator<Key>.
Table 28.10
▪ An associative container, which a variable size container that supports the efficient retrieval of
element values based on an associated key value. It is a simple associative container because its
element values are its key values.
▪ Reversible, because it provides a bidirectional iterator to access its elements.
▪ Sorted, because its elements are ordered by key values within the container in accordance with a
specified comparison function.
▪ Unique in the sense that each of its elements must have a unique key. Since set is also a simple
associative container, its elements are also unique.
- A set is also described as a template class because the functionality it provides is generic and
independent of the specific type of data contained as elements. The data type to be used is, instead,
specified as a parameter in the class template along with the comparison function and allocator.
- The elements of a set are unique and serve as their own sort keys. This type of structure is an ordered
list of, say, words in which the words may occur only once.
- If multiple occurrences of the words were allowed, then a multiset would be the appropriate container
structure.
- If unique definitions were attached as values to the list of key words, then a map would be an
appropriate structure to contain this data. If instead the definitions were not unique, then a multimap
would be the container of choice.
- The set orders the sequence it controls by calling a stored function object of type key_compare. This
stored object is a comparison function that may be accessed by calling the member function
key_comp.
- In general, the elements need to be merely less than comparable to establish this order so that, given
any two elements, it may be determined either that they are equivalent (in the sense that neither is less
than the other) or that one is less than the other. This results in an ordering between the nonequivalent
elements.
- The iterator provided by the set class is a bidirectional iterator, but the class member functions
insert() and set() have versions that take as template parameters a weaker input iterator, whose
functionality requirements are more minimal than those guaranteed by the class of bidirectional
iterators.
- The different iterator concepts form a family related by refinements in their functionality. Each iterator
concept has its own set of requirements, and the algorithms that work with them must limit their
assumptions to the requirements provided by that type of iterator.
- It may be assumed that an input iterator may be dereferenced to refer to some object and that it may be
incremented to the next iterator in the sequence.
- This is a minimal set of functionality, but it is enough to be able to talk meaningfully about a range of
iterators [_First, _Last) in the context of the class's member functions.
set Constructor
www.tenouk.com Page 13 of 29
- Constructs a set that is empty or that is a copy of all or part of some other set. The following is a code
for set constructor set::set. It is provided here for parameters terminologies reference and will not
be repeated for other associative containers.
set( );
explicit set(
const Traits& _Comp
);
explicit set(
const Traits& _Comp,
const Allocator& _Al
);
set(
const _set& _Right
);
template<class InputIterator>
set(
InputIterator _First,
InputIterator _Last
);
template<class InputIterator>
set(
InputIterator _First,
InputIterator _Last,
const Traits& _Comp
);
template<class InputIterator>
set(
InputIterator _First,
InputIterator _Last,
const Traits& _Comp,
const Allocator& _Al
);
Parameters
Parameter Description
_Al The storage allocator class to be used for this set object, which defaults to Allocator.
_Comp The comparison function of type const Traits used to order the elements in the set,
which defaults to Compare.
_Right The set of which the constructed set is to be a copy.
_First The position of the first element in the range of elements to be copied.
_Last The position of the first element beyond the range of elements to be copied.
Table 28.11
- All constructors store a type of allocator object that manages memory storage for the set and that can
later be returned by calling get_allocator(). The allocator parameter is often omitted in the class
declarations and preprocessing macros used to substitute alternative allocators.
- All constructors initialize their sets.
- All constructors store a function object of type Traits that is used to establish an order among the
keys of the set and that can later be returned by calling key_comp().
- The first three constructors specify an empty initial set, the second specifying the type of comparison
function (_Comp) to be used in establishing the order of the elements and the third explicitly
specifying the allocator type (_Al) to be used.
- The keyword explicit suppresses certain kinds of automatic type conversion.
- The fourth constructor specifies a copy of the set _Right.
- The last three constructors copy the range [_First, _Last) of a set with increasing explicitness in
specifying the type of comparison function of class Traits and Allocator.
Note:
- You will find somewhere sometime in STL the half-open ranges format as shown below.
- The range is defined so that it includes the position used as the beginning of the range but excludes the
position used as the end. It can be illustrated below:
www.tenouk.com Page 14 of 29
- From the illustration, begin() and end() define a half-open range that includes the first element but
excludes the last. A half-open range has two advantages:
1. You have a simple end criterion for loops that iterate over the elements, they simply continue
as long as end() is not reached.
2. It avoids special handling for empty ranges. For empty ranges, begin() is equal to end().
//set, constructor
#include <set>
#include <iostream>
using namespace std;
char main()
{
set <char>::iterator st0_Iter, st1_Iter, st2_Iter, st3_Iter, st4_Iter, st5_Iter, st6_Iter;
//------------------------------------------------
cout<<"Operation: set <char> st0\n";
cout<<"st0 data: ";
for(st0_Iter = st0.begin(); st0_Iter != st0.end(); st0_Iter++)
cout<<" "<<*st0_Iter;
cout<<endl;
www.tenouk.com Page 15 of 29
cout<<"\nOperation1: set <char, less<char> > st1\n";
cout<<"Operation2: st1.insert('p')...\n";
cout<<"st1 data: ";
for(st1_Iter = st1.begin(); st1_Iter != st1.end(); st1_Iter++)
cout<<" "<<*st1_Iter;
cout<<endl;
Output:
- The return value is 1 if the set contains an element whose sort key matches the parameter key. 0 if the
set does not contain an element with a matching key.
- The member function returns the number of elements in the following range:
//set, count()
www.tenouk.com Page 16 of 29
//some warning during the compilation
#include <set>
#include <iostream>
using namespace std;
int main()
{
set <int> st1;
int i;
st1.insert(1);
st1.insert(2);
st1.insert(1);
i = st1.count(2);
cout<<"The number of elements in st1 with a sort key of 2 is: "<<i<<endl;
i = st1.count(3);
cout<<"The number of elements in st1 with a sort key of 3 is: "<<i<<endl;
return 0;
}
Output:
- The return value is a pair of iterators where the first is the lower_bound of the key and the second is the
upper_bound of the key.
- To access the first iterator of a pair pr returned by the member function, use pr.first, and to
dereference the lower bound iterator, use *(pr.first).
- To access the second iterator of a pair pr returned by the member function, use pr.second, and to
dereference the upper bound iterator, use *(pr.second).
//set, equal_range()
//some warning during compilation
#include <set>
#include <iostream>
using namespace std;
int main()
{
typedef set<int, less<int> > IntSet;
IntSet st1;
set <int>::iterator st1Iter;
set <int, less< int > > :: const_iterator st1_RcIter;
st1.insert(10);
st1.insert(20);
st1.insert(30);
st1.insert(40);
st1.insert(50);
www.tenouk.com Page 17 of 29
<<"a key of 30 in the set st1 is: "
<<*(p1.first)<<endl;
cout<<"\nOperation: p2 = st1.equal_range(60)\n";
p2 = st1.equal_range(60);
Output:
- The return value is the function object that a set uses to order its elements, which is the template
parameter Traits.
- The stored object defines the member function:
- Which returns true if _xVal precedes and is not equal to _yVal in the sort order.
- Note that both key_compare and value_compare are synonyms for the template parameter
Traits.
- Both types are provided for the set and multiset classes, where they are identical, for compatibility with
the map and multimap classes, where they are distinct.
//set, key_comp()
#include <set>
#include <iostream>
using namespace std;
int main()
{
set <int, less<int> > st1;
set<int, less<int> >::key_compare kc1 = st1.key_comp();
bool res1 = kc1(3, 7);
if(res1 == true)
{
cout<<"kc1(3,7) returns value of true, "
<<"where kc1\nis the function object of st1."
<<endl;
}
else
{
www.tenouk.com Page 18 of 29
cout<<"kc1(3,7) returns value of false "
<<"where kc1\nis the function object of st1."
<<endl;
}
Output:
- The return value is an iterator or const_iterator that addresses the location of an element in a set
that with a key that is equal to or greater than the argument key or that addresses the location
succeeding the last element in the set if no match is found for the key.
//set, lower_bound()
#include <set>
#include <iostream>
using namespace std;
int main( )
{
set <int> st1;
set <int> :: const_iterator st1Iter, st1_PIter, st1_QIter;
st1.insert(11);
st1.insert(21);
st1.insert(30);
st1.insert(10);
st1.insert(22);
st1_QIter = st1.lower_bound(21);
cout<<"The element of set st1 with a key of 21 is: "
<<*st1_QIter<<endl;
st1_QIter = st1.lower_bound(60);
www.tenouk.com Page 19 of 29
st1_QIter = st1.lower_bound(*st1_PIter);
cout<<"The element of st1 with a key matching "
<<"that\nof the last element is: "
<<*st1_QIter<<endl;
return 0;
}
Output:
//set, upper_bound()
#include <set>
#include <iostream>
using namespace std;
int main()
{
set <int> st1;
set <int> :: const_iterator st1Iter, st1PIter, st1QIter;
st1.insert(9);
st1.insert(12);
st1.insert(20);
st1.insert(13);
st1.insert(11);
st1QIter = st1.upper_bound(9);
cout<<"The first element of set st1 with a key greater "
<<"than 9 is: "<<*st1QIter<<endl;
st1QIter = st1.upper_bound(22);
Output:
www.tenouk.com Page 20 of 29
- The return value is a function object that a set uses to order its elements, which is the template
parameter Traits.
- The stored object defines the member function:
- Which returns true if _xVal precedes and is not equal to _yVal in the sort order.
- Note that both value_compare and key_compare are synonyms for the template parameter
Traits. Both types are provided for the set and multiset classes, where they are identical, for
compatibility with the map and multimap classes, where they are distinct.
//set, value_comp()
#include <set>
#include <iostream>
using namespace std;
int main()
{
set <int, less<int> > st1;
set <int, less<int> >::value_compare vcom1 = st1.value_comp();
bool result1 = vcom1(5, 9);
if(result1 == true)
{
cout<<"vcom1(5,9) returns value of true, "
<<"\nwhere vcom1 is the function object of st1."
<<endl;
}
else
{
cout<<"vcom1(5,9) returns value of false, "
<<"\nwhere vcom1 is the function object of st1."
<<endl;
}
Output:
Note:
www.tenouk.com Page 21 of 29
- For other associative containers, program examples as shown before will not be presented again, except
the containers constructor, because they are similar.
- You can try on your own by using the same previous program examples, replace the containers and
keep other codes as it is. Recompile and re run. Start using your own brain and creativity. Be creative
:o).
-------------------------------------------End of set--------------------------------------
---www.tenouk.com---
28.6 Multiset
- A multiset is the same as a set except that duplicates are allowed. Thus, a multiset may contain
multiple elements that have the same value. It can be depicted as follows:
- The elements of a multiset may be multiple and serve as their own sort keys, so keys are not unique.
If the definitions were not unique, then a multimap would be the container of choice.
- The multiset orders the sequence it controls by calling a stored function object of type Compare. This
stored object is a comparison function that may be accessed by calling the member function
key_comp().
- The iterator provided by the multiset class is a bidirectional iterator.
multiset Members
multiset Typedefs
Typedef Description
allocator_type A type that represents the allocator class for the multiset object.
A type that provides a bidirectional iterator that can read a const element in
const_iterator
the multiset.
const_pointer A type that provides a pointer to a const element in a multiset.
A type that provides a reference to a const element stored in a multiset for
const_reference
reading and performing const operations.
A type that provides a bidirectional iterator that can read any const element
const_reverse_iterator
in the multiset.
A signed integer type that can be used to represent the number of elements
difference_type
of a multiset in a range between elements pointed to by iterators.
A type that provides a bidirectional iterator that can read or modify any
iterator
element in a multiset.
A type that provides a function object that can compare two keys to
key_compare
determine the relative order of two elements in the multiset.
A type that provides a function object that can compare two sort keys to
key_type
determine the relative order of two elements in the multiset.
pointer A type that provides a pointer to an element in a multiset.
reference A type that provides a reference to an element stored in a multiset.
A type that provides a bidirectional iterator that can read or modify an
reverse_iterator
element in a reversed multiset.
An unsigned integer type that can represent the number of elements in a
size_type
multiset.
The type that provides a function object that can compare two elements as
value_compare
sort keys to determine their relative order in the multiset.
value_type A type that describes an object stored as an element as a multiset in its
www.tenouk.com Page 22 of 29
capacity as a value.
Table 28.12
Table 28.13
- The STL multiset class is used for the storage and retrieval of data from a collection in which the
values of the elements contained need not be unique and in which they serve as the key values
according to which the data is automatically ordered.
- The key value of an element in a multiset may not be changed directly. Instead, old values must be
deleted and elements with new values inserted. The following code is the multiset template class.
template <
class Key,
class Compare = less<Key>,
class Allocator = allocator<Key>
>
Parameters
Parameter Description
Key The element data type to be stored in the multiset.
The type that provides a function object that can compare two element values as sort
Compare
keys to determine their relative order in the multiset. The binary predicate less<Key>
is the default value.
The type that represents the stored allocator object that encapsulates details about the
Allocator
multiset's allocation and de-allocation of memory. The default value is
allocator<Key>.
Table 28.14
www.tenouk.com Page 23 of 29
- The STL multiset class is:
▪ An associative container, which is a variable size container that supports the efficient retrieval of
element values based on an associated key value.
▪ Reversible, because it provides bidirectional iterators to access its elements.
▪ Sorted, because its elements are ordered by key values within the container in accordance with a
specified comparison function.
▪ Multiple in the sense that its elements do not need to have unique keys, so that one key value can
have many element values associated with it.
▪ A simple associative container because its element values are its key values.
▪ A template class, because the functionality it provides is generic and so independent of the
specific type of data contained as elements. The data type to be used is, instead, specified as a
parameter in the class template along with the comparison function and allocator.
multiset Constructor
- Constructs a multiset that is empty or that is a copy of all or part of some other multiset.
- All constructors store a type of allocator object that manages memory storage for the multiset and that
can later be returned by calling get_allocator(). The allocator parameter is often omitted in the
class declarations and preprocessing macros used to substitute alternative allocators.
- All constructors initialize their multiset.
- All constructors store a function object of type Compare that is used to establish an order among the
keys of the multiset and that can later be returned by calling key_comp().
- The first three constructors specify an empty initial multiset, the second specifying the type of
comparison function (_Comp) to be used in establishing the order of the elements and the third
explicitly specifying the allocator type (_Al) to be used.
- The fourth constructor specifies a copy of the multiset _Right.
- The last three constructors copy the range [_First, _Last) of a multiset with increasing
explicitness in specifying the type of comparison function and allocator.
//multiset, constructor
#include <set>
#include <iostream>
using namespace std;
int main()
{
multiset <int>::iterator mst0_Iter, mst1_Iter, mst2_Iter, mst3_Iter;
multiset <int>::iterator mst4_Iter, mst5_Iter, mst6_Iter;
www.tenouk.com Page 24 of 29
//multiset mst4, a copy of multiset mst1
multiset <int> mst4(mst1);
//-----------------------------------------------------
cout<<"Operation: multiset <int> mst0\n";
cout<<"mst0 data: ";
for(mst0_Iter = mst0.begin(); mst0_Iter != mst0.end(); mst0_Iter++)
cout<<" " <<*mst0_Iter;
cout<<endl;
Output:
www.tenouk.com Page 25 of 29
find() program example
- The return value is an iterator or const_iterator that addresses the first location of an
element with a specified key, or the location succeeding the last element in the multiset if no match is
found for the key.
- The member function returns an iterator that addresses an element in the multiset whose sort key is
equivalent to the argument key under a binary predicate that induces an ordering based on a less than
comparability relation.
- If the return value of find() is assigned to a const_iterator, the multiset object cannot be
modified. If the return value of find() is assigned to an iterator, the multiset object can be
modified.
//multiset, find()
#include <set>
#include <iostream>
using namespace std;
int main()
{
multiset <int> mst1;
multiset <int>::const_iterator mst1_QIter, mst1_PIter, mst1_RIter;
mst1.insert(6);
mst1.insert(2);
mst1.insert(14);
mst1.insert(6);
mst1.insert(10);
mst1_PIter = mst1.find(10);
cout<<"The first element of multiset mst1 with a key of 10 is: "
<<*mst1_PIter<<endl;
mst1_PIter = mst1.find(21);
www.tenouk.com Page 26 of 29
//The element at a specific location in the multiset can be
//found using a dereferenced iterator addressing the location
mst1_QIter = mst1.end();
mst1_QIter--;
mst1_PIter = mst1.find(*mst1_QIter);
cout<<"\nThe first element of mst1 with a\nkey matching "
<<"that of the last element is: "
<<*mst1_PIter<<endl;
Output:
//*****listsort.cpp******
//list, sort()
#include <list>
#include <iostream>
using namespace std;
int main()
{
list <int> ls1;
list <int>::iterator ls1Iter;
ls1.push_back(31);
ls1.push_back(12);
ls1.push_back(40);
ls1.push_back(15);
ls1.push_back(9);
ls1.push_back(44);
cout<<"\nOperation: ls1.sort()\n";
ls1.sort();
cout<<"After sorting, ls1 data: ";
for(ls1Iter = ls1.begin(); ls1Iter != ls1.end(); ls1Iter++)
cout<<" "<<*ls1Iter;
cout<<endl;
cout<<"\nOperation: ls1.sort(greater<int>())\n";
ls1.sort(greater<int>());
cout<<"Re sort with 'greater than' operation,\nls1 =";
for(ls1Iter = ls1.begin(); ls1Iter != ls1.end(); ls1Iter++)
cout<<" "<<*ls1Iter;
cout<<endl;
return 0;
}
www.tenouk.com Page 27 of 29
[bodo@bakawali ~]$ g++ listsort.cpp -o listsort
[bodo@bakawali ~]$ ./listsort
Operation: ls1.sort()
After sorting, ls1 data: 9 12 15 31 40 44
Operation: ls1.sort(greater<int>())
Re sort with 'greater than' operation,
ls1 = 44 40 31 15 12 9
//******setcount.cpp*******
//set, count()
//some warning during the compilation
#include <set>
#include <iostream>
using namespace std;
int main()
{
set <int> st1;
int i;
st1.insert(1);
st1.insert(2);
st1.insert(1);
i = st1.count(2);
cout<<"The number of elements in st1 with a sort key of 2 is: "<<i<<endl;
i = st1.count(3);
cout<<"The number of elements in st1 with a sort key of 3 is: "<<i<<endl;
return 0;
}
//******multisetfind.cpp******
//multiset, find()
#include <set>
#include <iostream>
using namespace std;
int main()
{
multiset <int> mst1;
multiset <int>::const_iterator mst1_QIter, mst1_PIter, mst1_RIter;
mst1.insert(6);
mst1.insert(2);
mst1.insert(14);
mst1.insert(6);
mst1.insert(10);
mst1_PIter = mst1.find(10);
cout<<"The first element of multiset mst1 with a key of 10 is: "
<<*mst1_PIter<<endl;
mst1_PIter = mst1.find(21);
www.tenouk.com Page 28 of 29
//If no match is found for the key, end() is returned
if(mst1_PIter == mst1.end())
cout<<"\nThe multiset mst1 doesn't have an element "
<<"with a key of 21"<<endl;
else
cout<<"\nThe element of multiset mst1 with a key of 21 is: "
<<*mst1_PIter<<endl;
mst1 data: 2 6 6 10 14
The first element of multiset mst1 with a key of 10 is: 10
----------------------------------------End of multiset-----------------------------------
---www.tenouk.com---
www.tenouk.com Page 29 of 29