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

ЖАНРЫ

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

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

Шрифт:

Пример 11.27. Применение итератора kstride_iter

#include "kstride_iter.hpp"

#include <algorithm>

#include <iterator>

#include <iostream>

using namespace std;

int main {

 int a[] = { 0, 1, 2, 3, 4, 5, 6, 7 };

 kstride_iter<int*, 2> first(a);

 kstride_iter<int*, 2> last(a + 8);

 copy(first, last, ostream_iterator<int>(cout, "\n"));

}

11.14.

Реализация динамической матрицы

Проблема

Требуется реализовать числовые матрицы, размерности которых (количество строк и столбцов) неизвестны на этапе компиляции.

Решение

В примере 11.28 показана универсальная и эффективная реализация класса динамической матрицы, использующая итератор с шагом из рецепта 11.12 и

valarray
.

Пример 11.28. matrix.hpp

#ifndef MATRIX_HPP

#define MATRIX_HPP

#include "stride_iter.hpp" // см. рецепт 11.12

#include <valarray>

#include <numeric>

#include <algorithm>

template<class Value_T>

class matrix {

public:

 // открытые имена, вводимые typedef

 typedef Value_T value_type;

 typedef matrix self;

 typedef value_type* iterator;

 typedef const value_type* const_iterator;

 typedef Value_T* row_type;

 typedef stride_iter<value_type*> col_type;

 typedef const value_type* const_row_type;

 typedef stride_iter<const value_type*> const_col_type;

 // конструкторы

 matrix : nrows(0), ncols(0), m {}

 matrix(int r, int c) : nrows(r), ncols(c), m(r * с) {}

 matrix(const self& x) : m(x.m), nrows(x.nrows), ncols(x.ncols) {}

 template<typename T>

 explicit matrix(const valarray<T>& x)

: m(x.size + 1), nrows(x.size), ncols(1) {

for (int i=0; i<x.size; ++i) m[i] = x[i];

 }

 // позволить конструирование из матриц других типов

 template<typename T> explicit matrix(const matrix<T>& x)

: m(x.size + 1), nrows(x.nrows), ncols(x.ncols) {

copy(x.begin, x.end, m.begin);

 }

// открытые функции

 int rows const { return nrows; }

 int cols const { return ncols; }

 int size const { return nrows * ncols; }

 //
доступ к элементам

 row_type row begin(int n) { return &m[n * cols]; }

 row_type row_end(int n) { return row_begin + cols; }

 col_type col_begin(int n) { return col_type(&m[n], cols); }

 col_type col_end(int n) { return col_begin(n) + cols; }

 const_row_type row_begin(int n) const { return &m[n * cols]; }

 const_row_type row_end(int n) const { return row_begin + cols; }

 const_col_type col_begin(int n) const { return col_type(&m[n], cols); }

 const_col_type col_end(int n) const { return col_begin + cols; }

 iterator begin { return &m[0]; }

 iterator end { return begin + size; }

 const_iterator begin const { return &m[0]; }

 const_iterator end const { return begin + size; }

 // операторы

 self& operator=(const self& x) {

m = x.m;

nrows = x.nrows;

ncols = x.ncols;

return *this;

 }

 self& operator=(value_type x) { m = x; return *this; }

 row_type operator[](int n) { return row_begin(n); }

 const_row_type operator[](int n) const { return row_begin(n); }

 self& operator+=(const self& x) { m += x.m; return *this; }

 self& operator-=(const self& x) { m -= x.m; return *this; }

 self& operator+=(value_type x) { m += x; return *this; }

 self& operator-=(value_type x) { m -= x; return *this; }

 self& operator*=(value_type x) { m *= x; return *this; }

 self& operator/=(value_type x) { m /= x; return *this; }

 self& operator%=(value_type x) { m %= x; return *this; }

 self operator- { return -m; }

 self operator+ { return +m; }

 self operator! { return !m; }

 self operator~ { return ~m; }

 // дружественные операторы

 friend self operator+(const self& x, const self& y) { return self(x) += y; }

 friend self operator-(const self& x, const self& y) { return self(x) -= y; }

 friend self operator+(const self& x, value_type y) { return self(x) += y; }

 friend self operator-(const self& x, value_type y) { return self(x) -= y; }

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