如何部分专门化模板化的c ++类?

时间:2016-03-10 15:45:53

标签: c++ templates c++11 partial-specialization

我写了一个类似的通用矩阵类:

template <std::size_t N, std::size_t M, class T>
class CMatrix
{
protected:
    T* m_elem;
public:
    CMatrix() : m_elem(new T[N*M]) {}
    ~CMatrix() { delete[] m_elem; }
    inline bCMatrix& operator*=(const T& val);
    inline bCMatrix& operator/=(const T& val);
    ...
    template <std::size_t L> inline CMatrix<L, N, T> operator*(const CMatrix<M, L, T>& mat) const;
};

现在我想为CMatrix&lt; 2,2,T&gt;做几个专业化。 我想添加一个comstructor CMatrix<2,2,T>(const T& a00, const T& a01, const T& a10, const T& a11) {...}。 并且我喜欢专门化CMatrix&lt; 2x2&gt; * CMatrix&lt; 2x2&gt;的矩阵乘法。但另一方面,我想保留* =和/ =等功能。

我该怎么做?

我唯一的工作尝试是重写(复制/过去/搜索/替换)专业化N = 3,M = 3的所有代码,如:

template <class T>
class CMatrix<3,3,T>
{
...
};

现在我可以专注于2x2的矩阵 - 矩阵乘法。但是我有两个几乎相同的代码片段,例如一个用于通用矩阵向量乘法,一个用于矩阵向量乘法用矩阵2x2。如果我优化通用的那么两者都必须改变。很难保持这一点。

1 个答案:

答案 0 :(得分:3)

您可以阅读有关课程模板的一些文档,例如http://en.cppreference.com/w/cpp/language/partial_specialization。对你来说,它需要以这样的方式定义专业化:

template<typename T>
class CMatrix<2, 2, T>
{
public:
    CMatrix<2,2,T>(const T& a00, const T& a01, const T& a10, const T& a11);
    ...
    template <std::size_t L> inline CMatrix<L, 2, T> operator*(const CMatrix<2, L, T>& mat) const;

    // Special overload for 2x2 x 2x2 multiplication
    inline CMatrix<2, 2, T> operator*(const CMatrix<2, 2, T>& mat) const;
};

为了防止重复operator*=等代码,你可以制作一个template<int M, int N, typename T> class CMatrixBase {}并在那里实现它们,并让你的实际矩阵类和特化继承。

Martin建议使用CRTP,它可以帮助您不丢失类型信息。这看起来像这样:

template<int M, int N, typename T, typename Derived>
class CMatrixBase
{
public:
    Derived& operator*=(T val) {
        doMultiplication(val);
        return *static_cast<Derived*>(this);
    }
};