我正在使用C ++ 14编写模板化矩阵类。该类有三个模板参数:存储的数据类型(dtype),行数(N)和列数(M)。
班级签名是
template<class dtype, size_t N, size_t M>
class Matrix
我编写了一个决定性成员函数,当模板参数具有特定值时,该函数调用特定情况。例如,当行数为1时,它返回矩阵本身的副本。或者,当行数为2或3时,它返回具有行列式的相同数据类型的1x1矩阵。最后,当行数大于3时,它使用递归方法根据行列式的辅因子扩展来计算行列式。
我这样做是为了更好地学习C ++ 14,所以我非常感谢你的帮助。
导致问题的代码段就在这里:
Matrix<dtype, 1, 1> det() const {
if (N != M || N >= 12) {
return Matrix<dtype, 1, 1>();
} else if (N == 1) {
return this->copy();
} else if (N == 2) {
return Matrix<dtype, 1, 1>(this->get(0, 0) * this->get(1, 1) - this->get(0, 1) * this->get(1, 0));
} else if (N == 3) {
return Matrix<dtype, 1, 1>(
this->get(0, 0) * (this->get(1, 1) * this->get(2, 2) - this->get(1, 2) * this->get(2, 1)) -
this->get(0, 1) * (this->get(1, 0) * this->get(2, 2) - this->get(1, 2) * this->get(2, 0)) +
this->get(0, 2) * (this->get(1, 0) * this->get(2, 1) - this->get(1, 1) * this->get(2, 0)));
} else if (N < 12) {
Matrix<dtype, 1, 1> determinant;
Matrix<dtype, N - 1, N - 1> sub_matrix;
for (size_t i = 0; i < N; ++i) {
sub_matrix = this->drop_cross(i, i);
Matrix<dtype, 1, 1> sub_det(sub_matrix.det());
if (i % 2 == 0) determinant = determinant + (this->get(0, i) * sub_det);
else if (i % 2 == 1) determinant = determinant - (this->get(0, i) * sub_det);
}
return determinant;
}
}
此代码调用此函数:
#include "lin_alg_classes.h"
int main() {
Matrix<double, 3, 3> test3(1.0, true);
std::cout << std::endl;
std::cout << test3.det();
return 0;
}
并提供以下输出:
In file included from C:\Users\ekin4\CLionProjects\mt_grav\main.cpp:5:0:
C:\Users\ekin4\CLionProjects\mt_grav\lin_alg_classes.h: In instantiation of 'Matrix<dtype, 1ull, 1ull> Matrix<dtype, N, M>::det() const [with dtype = double; long long unsigned int N = 3ull; long long unsigned int M = 3ull]':
C:\Users\ekin4\CLionProjects\mt_grav\main.cpp:29:28: required from here
C:\Users\ekin4\CLionProjects\mt_grav\lin_alg_classes.h:132:31: error: could not convert 'Matrix<dtype, N, M>::copy<double, 3ull, 3ull>()' from 'Matrix<double, 3ull, 3ull>' to 'Matrix<double, 1ull, 1ull>'
return this->copy();
我不明白为什么在它应该调用N&lt; N = 1时调用N = 1的情况。 12个案例。我检查了大括号,括号和分号,它们都是正确的,但对于我的生活,我不明白发生了什么。
答案 0 :(得分:1)
Pre c ++ 17(if constexpr
)您可以根据det()
和N
的值使用SFINAE并启用/停用不同版本的M
。
喜欢(抱歉:未经测试)
template <std::size_t A = N, std::size_t B = M>
std::enable_if_t<(A != B) || (A > 11U), Matrix<dtype, 1, 1>> det() const
{ return Matrix<dtype, 1, 1>(); }
template <std::size_t A = N, std::size_t B = M>
std::enable_if_t<(A == B) && (A == 1U), Matrix<dtype, 1, 1>> det() const
{ return this->copy(); }
// other cases