从父模板类转换为子模板类

时间:2018-10-28 21:37:21

标签: c++ templates inheritance

我有一个基本的模板类。

template <typename T, int width>
struct mat

派生的模板类之一是

template <typename T>
struct mat4 : public mat<T, 4>

但是当我尝试将两个矩阵相乘并分配它们时

mat4<float> model(1.0f);
mat4<float> model2(1.0f);
mat4<float> a = model * model2;

我收到错误C2440:'正在初始化':无法从'maths :: mat'转换为'maths :: mat4'。如何告诉编译器mat4<T>mat<T,4>彼此相等?因为到目前为止,它们被解释为不同的类型,这使赋值运算符无法工作,因为它无法从mat<T, 4>转换为mat4<T>

有关我的实施的其他信息:

operator =

template<typename T, int width>
inline mat<T, width>& mat<T, width>::operator=(const mat<T, width>& rhs)
{
    *this = rhs;
}

操作员*

template<typename T, int width>
inline mat<T, width> mat<T, width>::operator*(const mat<T, width>& rhs)const{
mat<T, width> ans;

for (int y = 0; y < width; y++)
{
    for (int x = 0; x < width; x++) {
        T elementSum = T(0);
        for (int f = 0; f < width; f++) {
            elementSum += elements[x + f * width] * rhs.elements[f + y * width];
        }
        ans.elements[x + y * width] = elementSum;
    }
}
return ans;

mat4构造函数

mat4(const T scalar = T())
    :mat<T, 4>{ scalar }
{};

垫子构造器

template<typename T, int width>
inline mat<T, width>::mat(const T scalar)
{
    for (int i = 0; i < cells; i++)
         ((i % (width+1)) == 0) ? (elements[i] = (T)1 * scalar)
                                : (elements[i] = (T)0);
}

2 个答案:

答案 0 :(得分:2)

您需要向mat4接受mat的转换构造函数:

template <typename T>
mat4<T>::mat4(const mat<T, 4> &that)
    : mat<T, 4>(that) { }

请注意,尽管mat4<float> a = model * model2;语句在语法上实际上没有使用赋值运算符。而是使用可用的非显式构造函数之一来生成copy initialization

答案 1 :(得分:1)

错误是因为在基数mat中定义的运算符正在返回对mat而不是mat4的引用,即使它们之间存在继承关系,也没有告诉编译器如何从mat4mat,记住 is-a 关系。

您需要的是mat4中的转换构造函数,如下所示:

template <typename T>
struct mat4 : public mat<T, 4>
{
    template <int width, typename std::enable_if<(width == 4), bool>::type = true>
    mat4(mat<T, width> const& b) : mat<T, width>(b)
    { }
};