Читаем Thinking In C++. Volume 2: Practical Programming полностью

    ostream_iterator(cout, ""));

  // Print sightings for selected animal:

  for(int count = 1; count < 10; count++) {

    // Use menu to get selection:

    // int i = menu();

    // Generate randomly (for automated testing):

    int i = rand() % animals.size();

    // Iterators in "range" denote begin, one

    // past end of matching range:

    pair range =

      sightings.equal_range(animals[i]);

    copy(range.first, range.second,

      ostream_iterator(cout, ""));

  }

} ///:~

All the data about a sighting is encapsulated into the class DataPoint, which is simple enough that it can rely on the synthesized assignment and copy-constructor. It uses the Standard C library time functions to record the time of the sighting.

In the array of string animal, notice that the char* constructor is automatically used during initialization, which makes initializing an array of string quite convenient. Since it’s easier to use the animal names in a vector, the length of the array is calculated, and a vector is initialized using the vector(iterator, iterator) constructor.

The key-value pairs that make up a Sighting are the string, which names the type of animal, and the DataPoint, which says where and when it was sighted. The standard pair template combines these two types and is typedefed to produce the Sighting type. Then an ostream operator<< is created for Sighting; this will allow you to iterate through a map or multimap of Sightings and print it out.

SightingGen generates random sightings at random data points to use for testing. It has the usual operator( ) necessary for a function object, but it also has a constructor to capture and store a reference to a vector, which is where the aforementioned animal names are stored.

A DataMap is a multimap of string-DataPoint pairs, which means it stores Sightings. It is filled with 50 Sightings using generate_n( ) and printed out. (Notice that because there is an operator<< that takes a Sighting, an ostream_iterator can be created.) At this point the user is asked to select the animal for which they want to see all the sightings . If you press q, the program will quit, but if you select an animal number, the equal_range( ) member function is invoked. This returns an iterator (DMIter) to the beginning of the set of matching pairs and an iterator indicating past-the-end of the set. Since only one object can be returned from a function, equal_range( ) makes use of pair. Since the range pair has the beginning and ending iterators of the matching set, those iterators can be used in copy( ) to print out all the sightings for a particular type of animal.

<p>Multisets</p>

You’ve seen the set, which allows only one object of each value to be inserted. The multiset is odd by comparison since it allows more than one object of each value to be inserted. This seems to go against the whole idea of "setness," in which you can ask, "Is ‘it’ in this set?" If there can be more than one "it," what does that question mean?.

With some thought, you can see that it makes little sense to have more than one object of the same value in a set if those duplicate objects are exactly the same (with the possible exception of counting occurrences of objects, but as seen earlier in this chapter that can be handled in an alternative, more elegant fashion). Thus, each duplicate object will have something that makes it "different" from the other duplicates—most likely different state information that is not used in the calculation of the key during the comparison. That is, to the comparison operation, the objects look the same, but they actually contain some differing internal state.

Like any STL container that must order its elements, the multiset template uses the less template by default to determine element ordering. This uses the contained classes’ operator<, but you can of course substitute your own comparison function.

Consider a simple class that contains one element that is used in the comparison and another that is not:

//: C07:MultiSet1.cpp

// Demonstration of multiset behavior

#include

#include

#include

#include

#include

using namespace std;

class X {

  char c; // Used in comparison

  int i; // Not used in comparison

  // Don't need default constructor and operator=

  X();

  X& operator=(const X&);

  // Usually need a copy-constructor (but the

  // synthesized version works here)

public:

  X(char cc, int ii) : c(cc), i(ii) {}

  // Notice no operator== is required

  friend bool operator<(const X& x, const X& y) {

    return x.c < y.c;

  }

  friend ostream& operator<<(ostream& os, X x) {

    return os << x.c << ":" << x.i;

  }

};

class Xgen {

  static int i;

  // Number of characters to select from:

  enum { span = 6 };

public:

  Xgen() { srand(time(0)); }

  X operator()() {

    char c = 'A' + rand() % span;

    return X(c, i++);

  }

};

Перейти на страницу:

Похожие книги

3ds Max 2008
3ds Max 2008

Одни уверены, что нет лучшего способа обучения 3ds Мах, чем прочитать хорошую книгу. Другие склоняются к тому, что эффективнее учиться у преподавателя, который показывает, что и как нужно делать. Данное издание объединяет оба подхода. Его цель – сделать освоение 3ds Мах 2008 максимально быстрым и результативным. Часто после изучения книги у читателя возникают вопросы, почему не получился тот или иной пример. Видеокурс – это гарантия, что такие вопросы не возникнут: ведь автор не только рассказывает, но и показывает, как нужно работать в 3ds Мах.В отличие от большинства интерактивных курсов, где работа в 3ds Мах иллюстрируется на кубиках-шариках, данный видеокурс полностью практический. Все приемы работы с инструментами 3ds Мах 2008 показаны на конкретных примерах, благодаря чему после просмотра курса читатель сможет самостоятельно выполнять даже сложные проекты.

Владимир Антонович Верстак , Владимир Верстак

Программирование, программы, базы данных / Программное обеспечение / Книги по IT