На этом шаге мы рассмотрим особенности использования функций, имеющих несколько состояний одновременно.
В следующем примере показано, как при помощи объекта функции имитировать функцию, обладающую несколькими состояниями одновременно.
//--------------------------------------------------------------------------- #include <vcl.h> #include <iostream> #include <iterator> #include <list> #include <algorithm> #include <conio.h> //необходимо для getch() #pragma hdrstop //--------------------------------------------------------------------------- #pragma argsused using namespace std; std::string ToRus(const std::string &in) { char *buff = new char [in.length()+1]; CharToOem(in.c_str(),buff); std::string out(buff); delete [] buff; return out; } template <class T> inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="") { typename T::const_iterator pos; std::cout << ToRus(optcstr); for (pos=coll.begin(); pos!=coll.end(); ++pos) { std::cout <<*pos <<' '; } std::cout << std::endl; } class IntSequence { private: int value; public: // Конструктор IntSequence (int initialValue) : value(initialValue) { } // "Вызов функции" int operator() () { return value++; } }; int main(int argc, char* argv[]) { list<int> coll; // Вставка значений от 1 до 9 generate_n (back_inserter(coll), // Начало 9, // Количество элементов IntSequence(1)); // Генератор значений PRINT_ELEMENTS(coll,"Исходный список:\n"); // Замена элементов от второго до предпоследнего значениями, // начинающимися с 42 generate (++coll.begin(), // Начало --coll.end(), // Конец IntSequence(42)); // Генератор значений PRINT_ELEMENTS(coll,"Список после преобразования:\n"); getch(); return 0; } //---------------------------------------------------------------------------
В данном примере объект функции генерирует последовательность целых чисел. При каждом вызове оператор () возвращает текущее значение счетчика и увеличивает его. Начальное значение счетчика передается в аргументе конструктора.
Два таких объекта функции используются алгоритмами generate() и generate_n(), записывающими сгенерированные значения в коллекцию. Выражение IntSequence(1) в следующей команде создает объект функции, инициализированный значением 1:
generate_n (back_inserter(coll), 9, IntSequence(1));
Алгоритм generate(n) использует его девять раз для записи элемента, поэтому объект генерирует значения от 1 до 9. Аналогично, выражение IntSequence(42) генерирует последовательность, начиная со значения 42. Алгоритм generate() заменяет элементы, начиная с ++coll.begin() и заканчивая --coll.end().
Результат выполнения программы выглядит так:
Рис.1. Результат работы приложения
Используя другие версии оператора (), вы сможете легко строить более сложные последовательности.
На следующем шаге мы закончим изучение этого вопроса.