Я пишу матричные классы. Взгляните на это определение:
template <typename T, unsigned int dimension_x, unsigned int dimension_y>
class generic_matrix
{
...
generic_matrix<T, dimension_x - 1, dimension_y - 1>
minor(unsigned int x, unsigned int y) const
{ ... }
...
}
template <typename T, unsigned int dimension>
class generic_square_matrix : public generic_matrix<T, dimension, dimension>
{
...
generic_square_matrix(const generic_matrix<T, dimension, dimension>& other)
{ ... }
...
void foo();
}
Класс generic_square_matrix предоставляет дополнительные функции, такие как умножение матриц.
Делать это не проблема:
generic_square_matrix<T, 4> m = generic_matrix<T, 4, 4>();
Можно назначить любую квадратную матрицу для M, даже если тип не является generic_square_matrix из-за конструктора. Это возможно, потому что данные не изменяются между дочерними элементами, только поддерживаемые функции. Это также возможно:
generic_square_matrix<T, 4> m = generic_square_matrix<T, 5>().minor(1,1);
То же преобразование применимо и здесь. Но теперь возникает проблема:
generic_square_matrix<T, 4>().minor(1,1).foo(); //problem, foo is not in generic_matrix<T, 3, 3>
Чтобы решить эту проблему, я бы хотел, чтобы generic_square_matrix :: minor возвращала generic_square_matrix вместо generic_matrix. Я думаю, что единственный возможный способ сделать это - использовать специализацию шаблонов. Но поскольку специализация в основном рассматривается как отдельный класс, я должен переопределить все функции. Я не могу вызвать функцию неспецифического класса, как вы это сделали бы с производным классом, поэтому я должен скопировать всю функцию.
Это не очень хорошее решение для общего программирования и много работы.
C ++ почти имеет решение для моей проблемы: виртуальная функция производного класса может возвращать указатель или ссылку на другой класс, отличный от базового класса, если этот класс является производным от класса, который возвращает базовый класс. generic_square_matrix является производным от generic_matrix, но функция не возвращает ни указатель, ни ссылку, поэтому здесь это не применимо.
Есть ли решение этой проблемы (возможно, с использованием совершенно другой структуры; мои единственные требования - чтобы размеры были параметром шаблона и чтобы квадратные матрицы могли иметь дополнительную функциональность).
Заранее спасибо,
Рууд