Д. Стефенс - C++. Сборник рецептов
- Название:C++. Сборник рецептов
- Автор:
- Жанр:
- Издательство:КУДИЦ-ПРЕСС
- Год:2007
- Город:Москва
- ISBN:5-91136-030-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Д. Стефенс - C++. Сборник рецептов краткое содержание
Данная книга написана экспертами по C++ и содержит готовые рецепты решения каждодневных задач для программистов на С++. Один из авторов является создателем библиотеки Boost Iostreams и нескольких других библиотек C++ с открытым исходным кодом. В книге затрагивается множество тем, вот лишь некоторые из них: работа с датой и временем; потоковый ввод/вывод; обработка исключений; работа с классами и объектами; сборка приложений; синтаксический анализ XML-документов; программирование математических задач. Читатель сможет использовать готовые решения, а сэкономленное время и усилия направить на решение конкретных задач.
C++. Сборник рецептов - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Требуется заполнить произвольный контейнер случайными числами.
Можно использовать функции generate
и generate_n
из заголовочного файла совместно с функтором, возвращающим случайные числа. Пример 11.13 показывает, как это можно сделать.
Пример 11.13. Инициализация контейнеров случайными числами
#include
#include
#include
#include
#include
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(clock()));
vector v(5);
generate(v.begin(), v.end(), RndIntGen(1, 6));
copy(v.begin(), v.end(), ostream_iterator(cout, "\n"));
}
Программа примера 11.13 должна выдать результат, подобный следующему.
3
1
2
6
4
Стандартная библиотека C++ содержит функции generate
и generate_n
, специально предназначенные для заполнения контейнеров значениями, полученными функцией генератора случайных чисел. Эти функции принимают нуль-арный функтор (указатель на функцию или объект-функцию без аргументов), результат которого присваивается соседним элементам контейнера. Пример реализации функции generate
и generate_n
показан в примере 11.14.
Пример 11.14. Пример реализации функций generate и generate_n
template
void generate(Iter_T first, Iter_T last, Fxn_T f) {
while (first != last) *first++ = f();
}
template
void generate_n(Iter_T first, int n, Fxn_T f) {
for (int i=0; i < n; ++i) *first++ = f();
}
11.8. Представление динамического числового вектора
Требуется иметь тип для манипулирования динамическими числовыми векторами.
Вы можете использовать шаблон valarray
из заголовочного файла . Пример 11.15 показывает, как можно использовать шаблон valarray
.
Пример 11.15. Применение шаблона valarray
#include
#include
using namespace std;
int main() {
valarray 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
T* valarray_begin(valarray& x) {
return &x[0];
}
template T* valarray_end(valarray& 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
#include
#include
template
class kvector {
public:
// открытые поля
Value_T m[N];
// открытые имена, вводимые typedef
typedef Value_T value_type;
typedef Value_T* iterator;
typedef const Value_T* const_iterator;
typedef Value_T& reference;
typedef const Value_T& const_reference;
typedef size_t size_type;
// определение более короткого синонима для kvector
typedef kvector self;
// функции-члены
template
void copy(Iter_T first, Iter_T last) {
copy(first, last, begin());
}
iterator begin() { return m; }
iterator end() { return m + N; }
const_iterator begin() const { return m; }
const_iterator end() const { return m + N; }
reference operator[](size_type n) { return m[n]; }
const_reference operator[](size_type n) const { return m[n]; }
static size_type size() { return N; }
// векторные операции
self& operator+=(const self& x) {
for (int i=0; i
return *this;
}
self& operator-=(const self& x) {
for (int i=0; i
return *this;
}
// скалярные операции
self& operator=(value_type x) {
std::fill(begin(), end(), x);
return *this;
}
self& operator+=(value_type x) {
for (int i=0; i
return *this;
}
self& operator-=(value_type x) {
for (int i=0; i
return *this;
}
self& operator*=(value_type x) {
for (int i=0; i
return *this;
}
self& operator/=(value_type x) {
for (int i=0; i
return *this;
}
self& operator%=(value_type x) {
for (int i=0; i
return *this;
}
self operator-() {
self x;
for (int i=n; i
return x;
}
// дружественные операторы
friend self operator+(self x, const self& y) { return x += у; }
friend self operator-(self x, const self& y) { return x -= y; }
friend self operator+(self x, value_type y) { return x += y; }
friend self operator-(self x, value_type y) { return x -= y; }
friend self operator*(self x, value_type y) { return x *= y; }
friend self operator/(self x, value_type y) { return x /= y; }
Интервал:
Закладка: