Основные выпуски
Есть много проблем с вашим кодом, которые Visual Studio не уловил, но все же нарушает код.
Например, в строках 86 и 87 вашего файла для вставки:
decltype (std::declval<T>()*std::declval<T2>()) T3;
Matrix<T3> result = Matrix<T3>::gen_full(this->lines(), other.cols());
Вы объявляете переменную с именем T3
, а затем пытаетесь использовать ее в качестве параметра шаблона для Matrix. Что должно быть:
// Declare T3 as a type
using T3 = decltype (std::declval<T>()*std::declval<T2>());
// Now we can use T3
Matrix<T3> result = Matrix<T3>::gen_full(this->lines(), other.cols());
Или здесь, в gen_full
:
template<class T>
Matrix<T> Matrix<T>::gen_full(unsigned int lines, unsigned int cols, T value){
for(unsigned int i = 0; i < lines; i++) {
std::vector<T> line;
for(unsigned int j = 0; j < cols; j++) {
line.push_back(value);
}
this->data.push_back(line); // Error here
}
};
Вы используете this
, но gen_full
является статической функцией, поэтому this
недоступен.
Мы можем переписать его как:
template<class T>
Matrix<T> Matrix<T>::gen_full(unsigned int lines, unsigned int cols, T value){
Matrix<T> m;
for(unsigned int i = 0; i < lines; i++) {
std::vector<T> line;
for(unsigned int j = 0; j < cols; j++) {
line.push_back(value);
}
m.data.push_back(line); // Error here
}
return m;
};
В строках 346 и 348 у вас та же проблема, что и в 86 и 87:
decltype(std::declval<T>() - std::declval<T2>()) T3;
Matrix<T3> res(this->lines(), this->cols());
Мы можем исправить это так же, как и там (с using T3 = decltype(...)
)
В строке 350 вы объявляете i
как const, а затем увеличиваете его. Мы можем просто удалить const
, и это работает.
Другие вопросы
Как только мы справились с основными проблемами, есть еще несколько других проблем, которые мы можем уловить, только пытаясь создать экземпляр класса.
Например, мы можем использовать фиктивную функцию, чтобы компилятор проверил это для нас:
void foo() {
// Forces the compiler to instantiate Matrix<double>
Matrix<double> A;
Matrix<double> B(A.tri_lo());
}
Когда мы пытаемся это сделать, мы получаем несколько загадочных ошибок, например, здесь, в строке 260:
Matrix<T> res(this->lines(), this->cols());
Gcc выдает ошибку
<source>: In instantiation of 'Matrix<T> Matrix<T>::tri_lo(bool) const [with T = double]':
<source>:365:31: required from here
<source>:262:15: error: passing 'const Matrix<double>' as 'this' argument discards qualifiers [-fpermissive]
262 | Matrix<T> res(this->lines(), this->cols());
| ^~~
Это означает, что вы пытаетесь использовать функции, которые не являются const (например, lines()
и cols()
) в контексте const (поскольку tri_lo
является const)
Мы можем исправить это, пометив lines()
и cols()
как const:
// On line 32 and 33
unsigned int cols() const; // Implemented
unsigned int lines() const; // Implemented
И здесь также:
// Lines 71 to 75
template<class T>
unsigned int Matrix<T>::cols() const { return this->data.size(); };
template<class T>
unsigned int Matrix<T>::lines() const { return this->data[0].size(); };
В чем причина первоначальной проблемы?
Насколько я могу судить, исходная проблема возникла из-за того, что lines()
и cols()
не были отмечены как const.
Заключение
Было много ошибок, которые Visual Studio не уловил. Рекомендуется использовать отдельный компилятор, такой как gcc
или clang
, который будет ловить ошибки быстрее и быстрее. Вы можете использовать их онлайн на https://godbolt.org, или вы можете установить их локально.
Вот оригинальная версия вашего кода вместе с ошибками, отображаемыми gcc: https://godbolt.org/z/5eiRNw
А вот обновленная версия вашего кода с исправленными ошибками (включая описанную в вашем исходном посте): https://godbolt.org/z/vFlyvk
Вам все еще нужно добавить реализацию Matrix<T>::gen_uninitialized
, и в строке 226 clang предупреждает вас, что std::vector<T> diag();
интерпретируется как прямое объявление функции с именем diag
(удалите скобки), но все остальное выглядит хорошо!