如果在模板参数比较为false时调用语句

时间:2017-09-17 19:52:50

标签: c++ class templates if-statement compiler-errors

我正在使用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个案例。我检查了大括号,括号和分号,它们都是正确的,但对于我的生活,我不明白发生了什么。

1 个答案:

答案 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