Шаблонный оператор шаблонного класса требует доступа к другим специализациям

0

Я реализовал матричный класс с использованием CRTP. Для матричного умножения я хотел бы использовать friend operator*. Проблема в том, что, согласно этому вопросу и моему собственному опыту, мне нужно определить operator* внутри класса, чтобы он работал.

Это означает, однако, что я должен повторно использовать параметры шаблона класса в определении, который дает доступ только к одной из трех матриц, участвующих в вычислении. Я не могу представить дружбу другим.

Пример кода:

template<template<unsigned, unsigned> class Child, unsigned M, unsigned N>
class BaseMatrix
{
    // This works, but does not give access to rhs or to the return value
    template<unsigned L>
        friend Child<M, L> operator*(const BaseMatrix<Child, M, N>& lhs, const BaseMatrix<Child, N, L>& rhs)
    {
        Child<M, L> result;
        result.v = lhs.v + rhs.v; // demo, of course
        return result;
    }

    // This compiles, but does not do anything
    template<template<unsigned, unsigned> class Child2, unsigned M2, unsigned N2, unsigned L>
        friend Child2<M2, N2> operator*(const BaseMatrix<Child2, M2, L>&, const     BaseMatrix<Child2, L, N2>&);

    // This produces an ambiguous overload
    template<unsigned L>
        friend Child<M, N> operator*(const BaseMatrix<Child, M, L>& lhs, const     BaseMatrix<Child, L, N>& rhs);

    double v;
};

template<unsigned M, unsigned N>
class ChildMatrix : public BaseMatrix<ChildMatrix, M, N>
{

};


int main()
{
    ChildMatrix<3, 4> a;
    ChildMatrix<4, 5> b;
    ChildMatrix<3, 5> c = a * b;

    return 0;
}

Как я могу предотвратить нарушения доступа к rhs.v и result.v?

Теги:
templates
friend
crtp

1 ответ

1

Не используйте для этого friend. Матричный класс должен выставлять свои элементы по отдельности, и этого достаточно для умножения на регулярную (недружественную) функцию.

  • 0
    ну да, но обычные функции доступа к элементам проверяют индексы для доступа за пределы, и я хотел бы избежать этого здесь. Кроме того, это должно быть возможно как-то, верно?
  • 0
    Просто сделайте то, что делает std :: vector: предоставьте один метод доступа, который проверяет границы (std :: vector :: at ()), и тот, который этого не делает ( operator[] в случае вектора, но вам нужно использовать круглые скобки для несколько измерений).
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню