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

ЖАНРЫ

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

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

Шрифт:

#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;

return *this;

 }

 self& operator%=(value_type x) {

for (int i=0; i<N; ++i) m[i] %= x;

return *this;

 }

 self operator- {

self x;

for (int i=n; i<N; ++i) x.m[i] = -m[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
.

Пример 11.18. Применение вектора kvector

#include "kvector.hpp"

#include <algorithm>

#include <numeric>

#include <iostream>

using namespace std;

int main {

 kvector<int, 4> v = { 1, 2, 3, 4 };

 cout << "sum = " << accumulate(v.begin, v.end, 0) << endl;

 v *= 3;

 cout << "sum = " << accumulated.begin, v.end, 0) << endl;

 v += 1;

 cout << "sum = " << accumulate(v.begin, v.end, 0) << endl;

}

Программа примера 11.18 выдаст следующий результат.

sum = 10

sum = 30

sum = 34

Обсуждение

Представленный в примере 11.17 шаблон

kvector
является гибридом
valarray
и шаблона массива, предложенного в TR1. Как и
valarray
, вектор
kvector
представляет собой последовательность значений заданного числового типа, однако подобно массиву
TR1::array
его размер известен на этапе компиляции.

Характерной особенностью шаблона

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

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