# Beispiellösung

#ifndef MATRIX_HPP
#define MATRIX_HPP

#include <cassert>
#include <cstddef>

enum class StorageOrder {ColMajor, RowMajor};

template<typename T>
struct Matrix {
const std::size_t m; /* number of rows */
const std::size_t n; /* number of columns */
const std::size_t incRow; /* stride between subsequent rows */
const std::size_t incCol; /* stride between subsequent columns */
T* data;

Matrix(std::size_t m, std::size_t n, StorageOrder order) :
m(m), n(n),
incRow(order == StorageOrder::ColMajor? 1: n),
incCol(order == StorageOrder::RowMajor? 1: m),
data(new T[m*n]) {
}

~Matrix() {
delete[] data;
}

Matrix(const Matrix&) = delete;
Matrix& operator=(const Matrix&) = delete;

const T& operator()(std::size_t i, std::size_t j) const {
assert(i < m && j < n);
return data[i*incRow + j*incCol];
}

T& operator()(std::size_t i, std::size_t j) {
assert(i < m && j < n);
return data[i*incRow + j*incCol];
}
};

#endif

#include <iomanip>
#include <iostream>
#include "matrix.hpp"

int main() {
Matrix<double> A(7, 8, StorageOrder::ColMajor);
for (std::size_t j = 0; j < A.n; ++j) {
for (std::size_t i = 0; i < A.m; ++i) {
A(i, j) = i * A.n + j;
}
}
std::cout << "A:" << std::endl;
for (std::size_t i = 0; i < A.m; ++i) {
for (std::size_t j = 0; j < A.n; ++j) {
std::cout << " " << std::setw(8) << A(i, j);
}
std::cout << std::endl;
}

Matrix<float> B(3, 3, StorageOrder::RowMajor);
for (std::size_t i = 0; i < B.m; ++i) {
for (std::size_t j = 0; j < B.n; ++j) {
B(i, j) = j * B.m + i;
}
}
std::cout << std::endl << "B:" << std::endl;
for (std::size_t i = 0; i < B.m; ++i) {
for (std::size_t j = 0; j < B.n; ++j) {
std::cout << " " << std::setw(8) << B(i, j);
}
std::cout << std::endl;
}
}

theon$g++ -Wall -o test-matrix test-matrix.cpp theon$ ./test-matrix
A:
0        1        2        3        4        5        6        7
8        9       10       11       12       13       14       15
16       17       18       19       20       21       22       23
24       25       26       27       28       29       30       31
32       33       34       35       36       37       38       39
40       41       42       43       44       45       46       47
48       49       50       51       52       53       54       55

B:
0        3        6
1        4        7
2        5        8
theon$ Gibt es auch Datentypen, mit denen es nicht klappt? An der folgenden Stelle setzt der new-Operator voraus, dass es einen parameterlosen Konstruktor für T gibt, da wir keine Parameter spezifizieren:  Matrix(std::size_t m, std::size_t n, StorageOrder order) : /* ... */ data(new T[m*n]) { }  Hier ist ein minimalistisches Beispiel mit der Klasse Double, die keinen parameterlosen Konstruktor zur Verfügung stellt: #include <iomanip> #include <iostream> #include "matrix.hpp" struct Double { Double(double value) : value(value) { } double value; }; int main() { Matrix<Double> A(7, 8, StorageOrder::ColMajor); }  theon$ g++ -Wall -o bad-matrix bad-matrix.cpp
matrix.hpp: In instantiation of 'Matrix::Matrix(std::size_t, std::size_t, StorageOrder) [with T = Double; std::size_t = long unsigned int]':
matrix.hpp:21:15: error: no matching function for call to 'Double::Double()'
data(new T[m*n]) {
^~~~~~~~~~
theon\$