The second lesson is more pointed: if you look long enough, there’s probably a way to do it in the STL
//: C07:SimpleGenerators.h
// Generic generators, including
// one that creates pairs
#include
#include
// A generator that increments its value:
template
class IncrGen {
T i;
public:
IncrGen(T ii) : i (ii) {}
T operator()() { return i++; }
};
// A generator that produces an STL pair<>:
template
class PairGen {
T1 i;
T2 j;
public:
PairGen(T1 ii, T2 jj) : i(ii), j(jj) {}
std::pair
return std::pair
}
};
namespace std {
// A generic global operator<<
// for printing any STL pair<>:
template
operator<<(ostream& os, const pair
return os << p.first << "\t"
<< p.second << endl;
}} ///:~
Both generators expect that T can be incremented, and they simply use operator++ to generate new values from whatever you used for initialization. PairGen creates an STL pair object as its return value, and that’s what can be placed into a map or multimap using insert( ).
The last function is a generalization of operator<< for ostreams, so that any pair can be printed, assuming each element of the pair supports a stream operator<<. (It is in namespace std for the strange name lookup reasons discussed in Chapter 5.) As you can see in the following, this allows the use of copy( ) to output the map:
//: C07:AssocInserter.cpp
// Using an insert_iterator so fill_n() and
// generate_n() can be used with associative
// containers
#include "SimpleGenerators.h"
#include
#include
#include
#include
#include
using namespace std;
int main() {
set
fill_n(inserter(s, s.begin()), 10, 47);
generate_n(inserter(s, s.begin()), 10,
IncrGen
copy(s.begin(), s.end(),
ostream_iterator
map
fill_n(inserter(m, m.begin()), 10,
make_pair(90,120));
generate_n(inserter(m, m.begin()), 10,
PairGen
copy(m.begin(), m.end(),
ostream_iterator
} ///:~
The second argument to inserter is an iterator, which is an optimization hint to help the insertion go faster (instead of always starting the search at the root of the underlying tree). Since an insert_iterator can be used with many different types of containers, with non-associative containers it is more than a hint—it is required.
Note how the ostream_iterator is created to output a pair; this wouldn’t have worked if the operator<< hadn’t been created, and since it’s a template, it is automatically instantiated for pair
The magic of maps
An ordinary array uses an integral value to index into a sequential set of elements of some type. A map is an
In a single-item container such as a vector or a list, only one thing is being held. But in a map, you’ve got two things: the