Преобразование из родительского шаблонного класса в дочерний шаблонный класс - PullRequest
0 голосов
/ 29 октября 2018

У меня есть базовый шаблонный класс.

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;
}

operator *

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 }
{};

конструктор mat

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 голосов
/ 29 октября 2018

Ошибка в том, что операторы, определенные в базе mat, возвращают ссылки на mat, а не mat4, даже если между ними существует отношение наследования, компилятору ничего не сказано, как перейти от mat4 к mat, помните отношение 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)
    { }
};
0 голосов
/ 29 октября 2018

Вам нужно добавить конвертирующий конструктор к mat4, который принимает mat:

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

Обратите внимание, что оператор mat4<float> a = model * model2; фактически не использует оператор присваивания, хотя он присутствует там синтаксически. Вместо этого инициализация копии происходит с использованием одного из доступных неявных конструкторов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...