Чтобы решить вашу проблему, вы можете использовать основанный на политике дизайн. Например, вы можете создать классы политик Storage и Shape.
class Diagonal {
public:
// the default storage facility of a Diagonal matrix
typedef Stack default_storage;
};
template <typename T, typename Shape = DefaultShape, typename Storage = DefaultStorage, unsigned Row, unsigned Col>
class Matrix : public Storage, Shape { // policy classes Storage and Shape
public:
template <typename T1, typename Shape1, typename Storage1, unsigned Row1, unsigned Col1>
friend Matrix<T1,Shape1,Storage1,Row1,Col1>& operator += (Matrix<T1,Shape1,Storage1,Row1,Col1> matrix1,Matrix<T,Shape,Storage,Row,Col> matrix2);
template <typename T1, typename Shape1, typename Storage1, unsigned Row1, unsigned Col1>
friend Matrix<T1,Diagonal,Storage1,Row1,Col1>& operator += (Matrix<T1,Diagonal,Storage1,Row1,Col1> matrix1,Matrix<T,Diagonal,Storage,Row,Col> matrix2);
template <typename T1, typename Shape1, typename Storage1, unsigned Row1, unsigned Col1>
friend Matrix<T,Shape,Storage,Row,Col>& operator + (Matrix<T,Shape,Storage,Row,Col> matrix1, Matrix<T,Shape,Storage,Row,Col> matrix2);
template <typename T1, typename Shape1, typename Storage1, unsigned Row1, unsigned Col1>
friend Matrix<T,Diagonal,Storage,Row,Col>& operator + (Matrix<T,Diagonal,Storage,Row,Col> matrix1, Matrix<T,Diagonal,Storage,Row,Col> matrix2);
// general template function
template <typename T, typename Shape, typename Storage, unsigned Row, unsigned Col>
Matrix<T,Shape,Storage,Row,Col>& operator + (Matrix<T,Shape,Storage,Row,Col> matrix1, Matrix<T,Shape,Storage,Row,Col> matrix2) {
Matrix<T,Shape,Storage,Row,Col>* result = new Matrix<T,Shape,Storage,Row,Col>();
for (unsigned i = 0; i < matrix1.getRowSize(); i++) { // getRowSize is a member function of policy class Storage
for (unsigned j = 0; j < matrix1.getRowSize(); j++) {
(*result)(i,j) = matrix1.getValue(i,j) + matrix2.getValue(i,j);
}
}
return *result;
}
// overloaded template function
template <typename T, typename Shape, typename Storage, unsigned Row, unsigned Col>
Matrix<T,Diagonal,Storage,Row,Col>& operator + (Matrix<T,Diagonal,Storage,Row,Col> matrix1, Matrix<T,Diagonal,Storage,Row,Col> matrix2) {
Matrix<T,Shape,Storage,Row,Col>* result = new Matrix<T,Shape,Storage,Row,Col>();
for (unsigned i = 0; i < matrix1.getRowSize(); i++) {
(*result)(i,i) = matrix1.getValue(i,i) + matrix2.getValue(i,i);
}
return *result;
}
// general template function
template <typename T, typename Shape, typename Storage, unsigned Row, unsigned Col>
Matrix<T,Shape,Storage,Row,Col>& operator += (Matrix<T,Shape,Storage,Row,Col> matrix1,Matrix<T,Shape,Storage,Row,Col> matrix2) {
Matrix<T,Shape,Storage,Row,Col>* result = new Matrix<T,Shape,Storage,Row,Col>(matrix1); // copy constructor
for (unsigned i = 0; i < matrix1.getRowSize(); i++) {
for (unsigned j = 0; j < matrix1.getRowSize(); j++) {
(*result)(i,j) = matrix1.getValue(i,j) + matrix2.getValue(i,j);
}
}
return *result;
}
// overloaded template function
template <typename T, typename Shape, typename Storage, unsigned Row, unsigned Col>
Matrix<T,Diagonal,Storage,Row,Col>& operator += (Matrix<T,Diagonal,Storage,Row,Col> matrix1,Matrix<T,Diagonal,Storage,Row,Col> matrix2) {
Matrix<T,Shape,Storage,Row,Col>* result = new Matrix<T,Shape,Storage,Row,Col>(matrix1); // copy constructor
for (unsigned i = 0; i < matrix1.getRowSize(); i++) {
(*result)(i,i) = matrix1.getValue(i,i) + matrix2.getValue(i,i);
}
return *result;
}
Основное преимущество использования дизайна на основе политик состоит в том, что ваши пользователи могут легко предоставлять свои собственные средства хранения и операции формования. Все, что вам нужно сделать, это дать им понятный интерфейс, чтобы они знали, как они могут создавать собственные хранилища и выполнять операции формования.