如何使模板专门化从泛型库继承而不引起递归



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

#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'的类型不完整,无法定义

您不能只使用一个模板类来实现这一点。需要第二个模板类和一些元编程来做这样的事情:

#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_implMatrix<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();
}

有点难看,但如果需要多个专业,最终可能会更干净。

您可以通过将Matrix拆分为两个类模板来实现这一点。

#include <iostream>
template <int a, int b>
class MatrixImpl {
public:
// some functions
void g () {
std::cout << "hi" << std::endl;
}
};
template <int a, int b>
class Matrix : public MatrixImpl <a, b> {};
template <int a>
class Matrix <a, a> : public MatrixImpl <a,a> {
public:
void f () {
std::cout << "hello" << std::endl;
}
};
int main () {
Matrix <3,3> m;
m.f(); // ok
m.g(); // ok
Matrix <3,4> n;
n.f(); // <- invalid
n.g(); // ok
}

最新更新