变量模板专用化

Variable template specialisation

本文关键字:专用 变量      更新时间:2023-10-16

>我有一个带状矩阵类,它继承自抽象矩阵类

template <typename T, std::size_t R, std::size_t B>
class BMatrix : public Matrix<T, R, R> {
...
};

我想要一个三对角矩阵类,我是如何做到这一点的(使用继承(

template <typename T, std::size_t R>
class TriMatrix : public BMatrix<T, R, 3> {
...
}

现在我不确定这是否是最好的选择(因为三对角矩阵有非常有效的方法,但没有那么多一般的带状矩阵(。虽然上述工作有效,但我想使用模板专业化。但是,我正在混合模板类型和变量。

有没有办法在不使用继承的情况下做到这一点?

例如类似

template <typename T, std::size_t R, >
class BMatrix<T, R, 3> {
...
} typedef TMatrix ??

如果我理解正确, 您可能具有部分专业化:

template <typename T, std::size_t R>
class BMatrix<T, R, 3> {
// ...
};

using设施

template <typename T, std::size_t R>
using TriMatrix = BMatrix<T, R, 3>;

你断言,通过专业化,你需要重新实现一切,这是正确的。有一些使用继承的解决方法(通用 BMatrix 和专用 BMatrix 都可以从公共基础继承(,但我想指出一些替代模式。

首先,如果你想坚持使用成员函数进行某些操作的当前类设计,你可以简单地实现泛型类中的所有内容,并使用static_assert来阻止某人在B!=3时使用特定方法。由于类模板成员函数在实际使用之前不会实例化它们,因此在它们不适用的泛型情况下,可以安全地使用这些函数。如果您想为通用情况已经存在不太理想的版本的算法提供更优化的实现,则可以使用if constexpr(或者干脆if如果两个替代将编译(。

template<int W, int H>
class Ellipse
{
int Radius() const
{
static_assert(W==H); // only applies to circles
return W;
}
float Circumference() const
{
if (W == H)
return 2*PI*W;
else
return ... // ellipse circumference is not trivial
}
};
// Handy type alias
template<int R> using Circle = Ellipse<R,R>;

其次,您可以选择不将所有操作实现为类成员,而是使用常规的非成员函数。这样,您可以修复某些参数并使用重载:

// Radius, only for circles
template<int R>
int Radius(Ellipse<R,R> e) { return R; }
// Circumference, generic case
template<int W, int H>
int Circumference(Ellipse<W,H> e) { return /* ... */; }
// Circumference, specific case for circles
template<int R>
int Circumference(Ellipse<R,R> e) { return 2*PI*R; }