首页 > 解决方案 > 如何使模板特化从通用基础继承而不引起递归?

问题描述

我正在尝试在我的程序中实现矩阵。方阵应该具有额外的功能,例如计算行列式,但它们还应该具有矩阵的所有功能。我尝试过这样做——部分专门化 Matrix 并使其继承自通用 Matrix。我在互联网上搜索过,但没有找到类似的东西,只有类型,但它不适用于非类型参数。

#include <iostream>

template <int a, int b>
class Matrix {
public:
    // some functions
    void g () {
        std::cout << "hi" << std::endl;
    }
};

template <int a>
class Matrix <a, a> : public Matrix <a,a> {
public:
    void f () {
        std::cout << "hello" << std::endl;
    }
};

int main () {
    Matrix <3,3> m;
    m.f();
   m.g();
}

Matrix 实际上是在尝试从自身继承,但出现错误

递归类型'矩阵'未定义 | 聚合 'Matrix<3, 3> m' 类型不完整,无法定义

标签: c++templatesmatrix

解决方案


你不能只用一个模板类来做到这一点。需要第二个模板类和一些元编程来执行以下操作:

#include <iostream>

template <int a, int b>
class Matrix_impl {
public:
    // some functions
    void g () {
        std::cout << "hi" << std::endl;
    }
};

template <int a>
class special_matrix_impl : public Matrix_impl<a,a> {
public:
    void f () {
        std::cout << "hello" << std::endl;
    }
};

template<int a, int b>
struct which_template {

    typedef Matrix_impl<a, b> type;
};

template<int a>
struct which_template<a, a> {

    typedef special_matrix_impl<a> type;
};

template<int a, int b>
using Matrix=typename which_template<a, b>::type;

int main () {
    Matrix <3,3> m;
    m.f();
    m.g();
}

这里真正的模板名称是Matrix_implspecial_matrix_impl,并Matrix<a,b>选择适当的一个。

或者,使用单个模板执行此操作的唯一方法是使用额外的默认模板参数来消除模板特化的歧义:

#include <iostream>

template <int a, int b, typename=void>
class Matrix {
public:
    // some functions
    void g () {
        std::cout << "hi" << std::endl;
    }
};

template <int a>
class Matrix <a, a, void> : public Matrix <a, a, int> {
public:
    void f () {
        std::cout << "hello" << std::endl;
    }
};

int main () {
    Matrix <3,3> m;
    m.f();
   m.g();
}

有点丑,但如果需要多种专业化,最终可能会变得更干净。


推荐阅读