Несмотря на немного академичный вид этого примера, не следует пытаться создавать итератор конца valarray
, используя выражение &x[х.size()]
. Если это сработает, то только случайно, поскольку индексация valarray
, выходящая за допустимый индексный диапазон, приводит к непредсказуемому результату.
Отсутствие в valarray
функций-членов begin
и end
, несомненно, противоречит стилю STL. Отсутствие этих функций подчеркивает то, что в valarray
реализуется модель, отличная от концепции контейнера STL. Несмотря на это, вы можете использовать valarray
в любом обобщенном алгоритме, где требуется итератор с произвольным доступом.
11.9. Представление числового вектора фиксированного размера
Требуется иметь эффективное представление числовых векторов фиксированного размера.
В программном обеспечении обычного типа часто более эффектный результат по сравнению с valarray
дает применение специальной реализации вектора, когда его размер заранее известен на этапе компиляции. Пример 11.17 показывает, как можно реализовать шаблон вектора фиксированного размера, названный здесь kvector
.
#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; }
friend self operator%(self x, value type y) { return x %= y; }
};
Пример 11.18 показывает, как можно применять шаблон класса kvector
.