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