1
+ // matrix类模板的成员函数定义
2
+ template <typename T>
3
+ user::matrix<T>::matrix(size_type n, size_type m) : N {n}, M {m} {
4
+ // 常量成员必须通过初始列来初始化
5
+ _element.resize (N); // 先改变_element的大小,这是行数
6
+ for (auto &row : _element) // 这样写方便些,注意row是引用形式
7
+ row.resize (M); // 对每一行进行resize,M为列数
8
+ // resize之后每个元素都是默认值value_type{},这样,一个矩阵构造就完成了
9
+ }
10
+ template <typename T>
11
+ user::matrix<T>::matrix(
12
+ std::initializer_list<std::initializer_list<value_type>> ilist
13
+ ) : N {ilist.size ()}, M {user::max_column (ilist)} {
14
+ // 在初值列中通过ilist和辅助函数确定行/列数
15
+ _element.resize (N); // 同样的道理,先改变_element的大小,代表行数
16
+ size_type i {0 }; // 循环变量
17
+ for (const auto &row : ilist) { // 访问initializer_list不能用下标运算符
18
+ _element[i].resize (M); // 对每一行进行resize,M代表列数
19
+ size_type j {0 }; // 也是循环变量
20
+ for (const auto &x : row) {
21
+ _element[i][j++] = x; // 注意++是后缀形式
22
+ }
23
+ ++i; // 别忘了循环迭代
24
+ } // 这样,一个矩阵构造就完成了
25
+ }
26
+ template <typename T>
27
+ auto user::matrix<T>::operator ()(size_type i, size_type j) -> reference {
28
+ if (i >= N) {
29
+ std::string msg {" Error: Row index " };
30
+ msg += std::to_string (i) + " >= " + std::to_string (N);
31
+ throw typename matrix<T>::index_error {msg};
32
+ // 靠加法运算符疯狂拼接,然后抛出
33
+ }
34
+ if (j >= M) {
35
+ std::string msg {" Error: Column index " };
36
+ msg += std::to_string (j) + " >= " + std::to_string (M);
37
+ throw typename matrix<T>::index_error {msg}; // 同上
38
+ }
39
+ return _element[i][j];
40
+ }
41
+ template <typename T>
42
+ auto user::matrix<T>::operator ()(size_type i, size_type j)const
43
+ -> const_reference {
44
+ if (i >= N) {
45
+ std::string msg {" Error: Row index " };
46
+ msg += std::to_string (i) + " >= " + std::to_string (N);
47
+ throw matrix<T>::index_error {msg};
48
+ }
49
+ if (j >= M) {
50
+ std::string msg {" Error: Column index " };
51
+ msg += std::to_string (j) + " >= " + std::to_string (M);
52
+ throw matrix<T>::index_error {msg};
53
+ }
54
+ return _element[i][j];
55
+ }
56
+ template <typename T>
57
+ auto user::matrix<T>::operator *(const T &val) -> matrix {
58
+ matrix mat {*this }; // 用*this来拷贝构造mat
59
+ for (auto &row : mat._element ) // 遍历每一行,每一个row都是一个valarray引用
60
+ row *= val; // std::valarray特有的乘赋值功能
61
+ return mat; // 返回值
62
+ }
63
+ template <typename T>
64
+ auto user::matrix<T>::transpose()const -> matrix{
65
+ matrix mat (M,N); // 行列数颠倒
66
+ for (size_type i = 0 ; i < N; ++i)
67
+ for (size_type j = 0 ; j < M; ++j)
68
+ mat (j,i) = operator ()(i,j); // 注意i,j别写错了,想清楚
69
+ return mat;
70
+ }
71
+ template <typename T>
72
+ auto user::matrix<T>::size()const noexcept
73
+ -> std::pair<size_type, size_type> {
74
+ return typename std::pair<size_type, size_type> {N, M}; // 不需要typename,但可以有
75
+ }
76
+ // matrix类模板相关的非成员函数定义
77
+ template <typename T>
78
+ auto user::operator +(const matrix<T> &lhs, const matrix<T> &rhs)
79
+ -> matrix<T> {
80
+ if (lhs.N != rhs.N || lhs.M != rhs.M ) {
81
+ std::string msg {" Cannot add " };
82
+ msg += std::to_string (lhs.N ) + " * " + std::to_string (lhs.M )
83
+ + " matrix to " + std::to_string (rhs.N )
84
+ + " * " + std::to_string (rhs.M ) + " matrix" ;
85
+ throw typename matrix<T>::invalid_plus {msg};
86
+ }
87
+ matrix mat {lhs}; // 用lhs为mat赋值
88
+ for (std::size_t i = 0 ; i < lhs.N ; ++i)
89
+ mat._element [i] += rhs._element [i]; // 再加上rhs的每一行
90
+ return mat;
91
+ }
92
+ template <typename T>
93
+ auto user::operator -(const matrix<T> &lhs, const matrix<T> &rhs)
94
+ -> matrix<T> {
95
+ if (lhs.N != rhs.N || lhs.M != rhs.M ) {
96
+ std::string msg {" Cannot add " };
97
+ msg += std::to_string (lhs.N ) + " * " + std::to_string (lhs.M )
98
+ + " matrix from " + std::to_string (rhs.N )
99
+ + " * " + std::to_string (rhs.M ) + " matrix" ;
100
+ throw typename matrix<T>::invalid_plus {msg};
101
+ }
102
+ matrix mat {lhs};
103
+ for (std::size_t i = 0 ; i < lhs.N ; ++i)
104
+ mat._element [i] -= rhs._element [i]; // 再减去rhs的每一行
105
+ return mat;
106
+ }
107
+ template <typename T>
108
+ auto user::operator *(const matrix<T> &lhs, const matrix<T> &rhs)
109
+ -> matrix<T> {
110
+ if (lhs.M != rhs.N ) {
111
+ std::string msg {" Cannot multiply matrix with " };
112
+ msg += std::to_string (lhs.M ) + " columns by matrix with "
113
+ + std::to_string (rhs.N ) + " rows" ;
114
+ throw typename matrix<T>::invalid_multiplies{msg};
115
+ }
116
+ matrix<T> mat (lhs.N , rhs.M ); // 新建一个空的矩阵
117
+ for (std::size_t i = 0 ; i < lhs.N ; ++i)
118
+ for (std::size_t j = 0 ; j < rhs.M ; ++j)
119
+ for (std::size_t k = 0 ; k < lhs.M ; ++k)
120
+ mat (i,j) += lhs (i,k) * rhs (k,j); // 三重循环,就不讲了
121
+ return mat;
122
+ }
123
+ template <typename T>
124
+ auto user::operator *(const T &value, const matrix<T> &mat) -> matrix<T> {
125
+ return mat * value; // 节省代码,就这样写了
126
+ }
127
+ template <typename T>
128
+ bool user::operator <(const matrix<T> &lhs, const matrix<T> &rhs) {
129
+ if (lhs.N != rhs.N || lhs.M != rhs.M ) {
130
+ std::string msg {" Cannot compare " };
131
+ msg += std::to_string (lhs.N ) + " * " + std::to_string (lhs.M )
132
+ + " matrix with " + std::to_string (rhs.N ) + " * "
133
+ + std::to_string (rhs.M ) + " matrix" ;
134
+ throw typename matrix<T>::invalid_compare {msg};
135
+ }
136
+ for (std::size_t i = 0 ; i < lhs.N ; ++i)
137
+ if (lhs._element [i] < rhs._element [i])
138
+ return true ;
139
+ else if (lhs._element [i] > rhs._element [i])
140
+ return false ;
141
+ return false ;
142
+ }
143
+ template <typename T>
144
+ bool user::operator >(const matrix<T> &lhs, const matrix<T> &rhs) {
145
+ return rhs < lhs;
146
+ }
147
+ template <typename T>
148
+ bool user::operator <=(const matrix<T> &lhs, const matrix<T> &rhs) {
149
+ return !(rhs < lhs);
150
+ }
151
+ template <typename T>
152
+ bool user::operator >=(const matrix<T> &lhs, const matrix<T> &rhs) {
153
+ return !(lhs < rhs);
154
+ }
155
+ template <typename T>
156
+ bool user::operator !=(const matrix<T> &lhs, const matrix<T> &rhs) {
157
+ if (lhs.N != rhs.N || lhs.M != rhs.M ) {
158
+ std::string msg {" Cannot compare " };
159
+ msg += std::to_string (lhs.N ) + " * " + std::to_string (lhs.M )
160
+ + " matrix with " + std::to_string (rhs.N ) + " * "
161
+ + std::to_string (rhs.M ) + " matrix" ;
162
+ throw typename matrix<T>::invalid_compare {msg};
163
+ }
164
+ for (std::size_t i = 0 ; i < lhs.N ; ++i)
165
+ if (lhs._element [i] != rhs._element [i])
166
+ return true ;
167
+ return false ;
168
+ }
169
+ template <typename T>
170
+ bool user::operator ==(const matrix<T> &lhs, const matrix<T> &rhs) {
171
+ return !(lhs != rhs);
172
+ }
173
+ // 辅助函数定义
174
+ template <typename T>
175
+ std::size_t user::max_column (
176
+ const std::initializer_list<std::initializer_list<T>> &ilist
177
+ ) {
178
+ std::size_t result {}; // 初始化为0
179
+ for (auto row : ilist)
180
+ if (result < row.size ())
181
+ result = row.size ();
182
+ return result; // 返回的就是二维列表各行的最大值
183
+ }
0 commit comments