valarray
состоит в наличии многочисленных перегруженных операторов, предназначенных для работы с числовыми векторами. Эти операторы обеспечивают выполнение таких операций, как сложение и скалярное умножение векторов.
Шаблон valarray
может также использоваться в стандартных алгоритмах, работающих с массивами, представленными в C-стиле. Пример 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
.
#include <algorithm>
#include <cassert>
template<class Value_T, unsigned int N>
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<typename Iter_T>
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<N; ++i) m[i] += x.m[i];
return *this;
}
self& operator-=(const self& x) {
for (int i=0; i<N; ++i) m[i] -= x.m[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<N; ++i) m[i] += x;
return *this;
}
self& operator-=(value_type x) {
for (int i=0; i<N; ++i) m[i] -= x;
return *this;
}
self& operator*=(value_type x) {
for (int i=0; i<N; ++i) m[i] *= x;
return *this;
}
self& operator/=(value_type x) {
for (int i=0; i<N; ++i) m[i] /= x;