Чтение онлайн

ЖАНРЫ

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

#include <algorithm>

#include <vector>

#include <iterator>

#include <iostream>

#include <cstdlib>

using namespace std;

struct RndIntGen {

 RndIntGen(int l, int h) : low(l), high(h) {}

 int operator const {

return low + (rand % ((high - low) + 1));

 }

private:

 int low;

 int high;

};

int main {

 srand(static_cast<unsigned int>(clock));

 vector<mt> v(5);

 generate(v.begin, v.end, RndIntGen(1, 6));

 copy(v.begin, v.end, ostream_iterator<int>(cout, "\n"));

}

Программа

примера 11.13 должна выдать результат, подобный следующему.

3

1

2

6

4

Обсуждение

Стандартная библиотека C++ содержит функции

generate
и
generate_n
, специально предназначенные для заполнения контейнеров значениями, полученными функцией генератора случайных чисел. Эти функции принимают нуль-арный функтор (указатель на функцию или объект-функцию без аргументов), результат которого присваивается соседним элементам контейнера. Пример реализации функции
generate
и
generate_n
показан в примере 11.14.

Пример 11.14. Пример реализации функций generate и generate_n

template<class Iter_T, class Fxn_T>

void generate(Iter_T first, Iter_T last, Fxn_T f) {

 while (first != last) *first++ = f;

}

template<class Iter_T, class Fxn_T>

void generate_n(Iter_T first, int n, Fxn_T f) {

 for (int i=0; i < n; ++i) *first++ = f;

}

11.8. Представление динамического числового вектора

Проблема

Требуется иметь тип для манипулирования динамическими числовыми векторами.

Решение

Вы можете использовать шаблон

valarray
из заголовочного файла
<valarray>
. Пример 11.15 показывает, как можно использовать шаблон
valarray
.

Пример 11.15. Применение шаблона valarray

#include <valarray>

#include <iostream>

using namespace std;

int main {

 valarray<int> v(3);

 v[0] = 1;

 v[1] = 2;

 v[2] = 3;

 cout << v[0] << ", " << v[1] << ", " << v[2] << endl;

 v = v + v;

 cout << v[0] << ", " << v[1] << ", " << v[2] << endl;

 v /= 2;

 cout << v[0] << ", " << v[1] << ", " << v[2] << endl;

}

Программа

примера 11.15 выдаст следующий результат.

1, 2, 3

2, 4, 6

1, 2, 3

Обсуждение

Вопреки своему названию тип

vector
не предназначен для использования в качестве числового вектора, для этой цели используется шаблон
valarray
. Этот шаблон написан так, чтобы в конкретных реализациях С++, особенно на высокопроизводительных машинах, можно было применить к нему специальную векторную оптимизацию. Другое большое преимущество
valarray
состоит в наличии многочисленных перегруженных операторов, предназначенных для работы с числовыми векторами. Эти операторы обеспечивают выполнение таких операций, как сложение и скалярное умножение векторов.

Шаблон

valarray
может также использоваться в стандартных алгоритмах, работающих с массивами, представленными в C-стиле. Пример 11.16 показывает, как можно создавать итераторы, ссылающиеся на начальный элемент
valarray
и на элемент, следующий за последним.

Пример 11.16. Получение итераторов для valarray

template<class T>

T* valarray_begin(valarray<T>& x) {

 return &x[0];

}

template<class T> T* valarray_end(valarray<T>& x) {

 return valarray_begin(x) + x.size;

}

Несмотря на немного академичный вид этого примера, не следует пытаться создавать итератор конца

valarray
, используя выражение
&x[х.size]
. Если это сработает, то только случайно, поскольку индексация
valarray
, выходящая за допустимый индексный диапазон, приводит к непредсказуемому результату.

Отсутствие в

valarray
функций-членов
begin
и
end
, несомненно, противоречит стилю STL. Отсутствие этих функций подчеркивает то, что в
valarray
реализуется модель, отличная от концепции контейнера STL. Несмотря на это, вы можете использовать
valarray
в любом обобщенном алгоритме, где требуется итератор с произвольным доступом.

11.9. Представление числового вектора фиксированного размера

Проблема

Требуется иметь эффективное представление числовых векторов фиксированного размера.

Решение

В программном обеспечении обычного типа часто более эффектный результат по сравнению с

valarray
дает применение специальной реализации вектора, когда его размер заранее известен на этапе компиляции. Пример 11.17 показывает, как можно реализовать шаблон вектора фиксированного размера, названный здесь
kvector
.

Пример 11.17. kvector.hpp

Поделиться с друзьями: