Попытка написать шаблонный класс для матричного объекта.Получение ошибок компиляции:
c: \ program files (x86) \ microsoft visual studio 11.0 \ vc \ include \ xmemory0 (606): ошибка C2558: класс 'Matrix': не доступен конструктор копирования или копияконструктор объявлен как «явный» 1> с 1> [1> T = float 1>] 1> c: \ program files (x86) \ microsoft visual studio 11.0 \ vc \ include \ xmemory0 (605): при компиляции члена шаблона классафункция 'void std :: allocator <_Ty> :: construct (_Ty *, const _Ty &)' 1>
с 1> [1> _Ty = Matrix 1>] 1> c: \ программные файлы (x86) \Microsoft Visual Studio 11.0 \ vc \ include \ xmemory0 (751): см. ссылку на создание шаблона функции 'void std :: allocator <_Ty> :: construct (_Ty *, const _Ty &)', компилируемого 1> с 1> [1>
_Ty = Matrix 1>] 1> c: \ program files (x86) \ microsoft visual studio 11.0 \ vc \ include \ type_traits (743): см. Ссылку на создание шаблона класса 'std :: allocator <_Ty>'компилируется 1> с помощью 1> [1>
_Ty = Matrix 1>] 1> c: \ program files (x86) \ microsoft visual studio 11.0 \ vc \ include \ vector (655): см. Ссылку на экземпляр шаблона класса 'std :: is_empty <_Ty>', скомпилированный 1> с 1> [1>
_Ty = std :: allocator> 1>] 1> e: \ projects \ work \nns \ fifteenstepstut \ fifteensteps \ fifteensteps \ source.cpp (35): см. ссылку на создание экземпляра шаблона класса 'std :: vector <_Ty>' скомпилированным 1> с 1> [1>
_Ty = Matrix 1>] 1> 1> Сборка НЕ удалась.1>
И
ClCompile: 1> Source.cpp 1> e: \ projects \ work \ nns \ fifteenstepstut \ fifteensteps \ fifteensteps \ matrix.h (80): ошибка C2664: «Matrix :: Matrix (Matrix &)»: невозможно преобразовать параметр 1 из «Matrix (__cdecl *) (void)» в «Matrix &» 1>
с 1> [1> T = float1>] 1>
e: \ projects \ work \ nns \ fifteenstepstut \ fifteensteps \ fifteensteps \ matrix.h (74): при компиляции функции-члена шаблона класса 'Matrix Matrix :: dot (const Matrix &)' 1>с 1> [1>
T = float 1>] 1>
e: \ projects \ work \ nns \ fifteenstepstut \ fifteensteps \ fifteensteps \ source.cpp (62): см. ссылку на создание экземпляра шаблона функции 'МатрицаMatrix :: dot (const Matrix &) 'компилируется 1> с 1> [1> T = float 1>] 1>
e: \ projects \ work \ nns \ fifteenstepstut \ fifteensteps \ fifteensteps \ source.cpp (38): см. Ссылку на экземпляр шаблона класса 'Matrix', компилируемый 1> с 1> [1> T = float 1>
] 1> e: \ projects \ work \ nns \ fifteenstepstut \ fifteensteps \ fifteensteps \ matrix.ч (84): ошибатьсяили C2664: «Matrix :: Matrix (Matrix &)»: невозможно преобразовать параметр 1 из «Matrix (__cdecl *) (void)» в «Matrix &» 1>
с 1> [1> T = float 1>] 1> 1> Build FAILED.
"Matrix.h"
#include <vector>
#include <iostream>
template<typename T>
class Matrix {
private:
std::vector<T> data;
int rows;
int cols;
public:
Matrix();
Matrix(std::vector<T>, int rows, int cols);
Matrix(Matrix<T>&); //change with this one
//Matrix(const Matrix<T>&); //Will need to uncomment to test the 3rd error
void print();
Matrix<T> transpose();
Matrix<T> dot(const Matrix<typename std::remove_reference<T>::type> &); //error 2
//Matrix<T&> dot(const Matrix<T> &); //dumb idea?
//Matrix<T> dot(const Matrix<T> &); //error 1
};
template <typename T>
Matrix<T>::Matrix() {
data.clear();
rows = 0;
cols = 0;
}
template <typename T>
Matrix<T>::Matrix(std::vector<T> elements, int numRows, int numCols) {
rows = numRows;
cols = numCols;
data.clear();
for(unsigned int i = 0; i < elements.size(); i++) {
data.push_back(elements[i]);
}
}
template <typename T>
Matrix<T>::Matrix(Matrix<T>& matrix) {
rows = matrix.rows;
cols = matrix.cols;
data.clear();
for(unsigned int i = 0; i < matrix.data.size(); i++) {
data.push_back(matrix.data[i]);
}
}
/* To get compiler error, exchange with a above
template <typename T>
Matrix<T>::Matrix(const Matrix<T>& matrix) {
rows = matrix.rows;
cols = matrix.cols;
data.clear();
for(unsigned int i = 0; i < matrix.data.size(); i++) {
data.push_back(matrix.data[i]);
}
}*/
template <typename T>
Matrix<T> Matrix<T>::dot(const Matrix<typename std::remove_reference<T>::type> & rhs) { //ERROR 2
//Matrix<&T> dot(const Matrix<T> &) {
//Matrix<T> dot(const Matrix<T> &) { ERROR 1
if(cols != rhs.rows) {
std::cout << "Error! Can not resolve dot product on these matrices!" << std::endl;
std::cout << "Requested: [" << rows << "x" << cols << "] <alt+7> [" << rhs.rows << "x" << rhs.cols << "]" << std::endl;
Matrix<T> matrix();
return matrix;
}
Matrix<T> matrix();
return matrix;
}
template <typename T>
void Matrix<T>::print() {
for(unsigned int i = 0; i < data.size(); i++) {
std::cout << data[i] << ", ";
if((i+1) % cols == 0)
std::cout << std::endl;
}
}
template <typename T>
Matrix<T> Matrix<T>::transpose() {
std::vector<T> vec;
for(unsigned int i = 0; i < data.size(); i++) {
vec.push_back(data[(cols*(i%rows)+i/rows)]);
}
return Matrix<T>(vec, cols, rows);
}
Я читал несколько разных идей о том, как это исправить, но не совсем уверен, чтовопрос есть.Во многих местах говорится о передаче только T как константной ссылки, но в этом случае я передаю класс как константную ссылку.Похоже, что это не так.
Я наконец решил посмотреть, что произойдет, если реализовать конструктор ссылки на const.
Затем я получу эту ошибку:
неразрешенный внешний символ "public: class Matrix __thiscall Matrix :: dot (class Matrix const &)" (? dot @? $ Matrix @ M @@ QAE? AV1 @ ABV1 @@ Z), на который имеется ссылка в функции "void __cdecl testMatrixClass (void)"(? testMatrixClass @@ YAXXZ)
Как я могу выполнить передачу этого класса в качестве ссылки на const, если это вообще возможно?
Спасибо!
Выполнение теста
SOURCE.CPP
#include <iostream>
#include <vector>
#include "Matrix.h"
#include <string>
#include <fstream>
#include <sstream>
////TODO: Find alternatives to these...
//typedef std::vector<std::vector<float>> Matrix;
//typedef std::vector<float> Vector;
//using LMath::operator+;
//using LMath::operator==;
//void testMatrix(); //testing function.
//Matrix loadData(std::string); //Not implemented yet
//bool saveData(Matrix, std::string); //Not implemented yet
void testMatrixClass();
int main() {
//testMatrix();
testMatrixClass();
return 0;
}
void testMatrixClass() {
std::vector<Matrix<float>> testResults;
std::vector<std::string> testInfo;
Matrix<float> temp;
testResults.push_back(temp);
testInfo.push_back("Default Constructor");
std::vector<float> tempVec;
for(int i = 0; i < 9; i++) {
tempVec.push_back((float)(i%3));
}
Matrix<float> temp2(tempVec, 3, 3);
testResults.push_back(temp2);
testInfo.push_back("Vector constructor");
testResults.push_back(temp2.transpose());
testInfo.push_back("Vector transpose");
tempVec.push_back(10.0);
Matrix<float> temp3(tempVec, 5, 2);
testResults.push_back(temp3);
testInfo.push_back("Vector constructor");
testResults.push_back(temp3.transpose());
testInfo.push_back("Vector transpose");
testResults.push_back(temp2.dot(temp2));
testInfo.push_back("Dot product");
testResults.push_back(temp2.dot(temp3));
testInfo.push_back("Error Dot Product");
for(unsigned int i = 0; i < testResults.size(); i++) {
std::cout << "Test: " << testInfo[i] << ": " << std::endl;;
testResults[i].print();
std::cout << std::endl;
}
}
Решение:
#include <iostream>
#include <vector>
template<typename T>
class Matrix {
private:
std::vector<T> data;
int rows;
int cols;
public:
Matrix();
Matrix(std::vector<T>, int rows, int cols);
//Matrix(Matrix<T>&);
Matrix(const Matrix<T>&);
void print();
Matrix<T> transpose();
Matrix<T> dot(const Matrix<typename std::remove_reference<T>::type> &);
};
template <typename T>
Matrix<T>::Matrix() {
data.clear();
rows = 0;
cols = 0;
}
template <typename T>
Matrix<T>::Matrix(std::vector<T> elements, int numRows, int numCols) {
rows = numRows;
cols = numCols;
data.clear();
for(unsigned int i = 0; i < elements.size(); i++) {
data.push_back(elements[i]);
}
}
template <typename T>
Matrix<T>::Matrix(const Matrix<T>& matrix) {
rows = matrix.rows;
cols = matrix.cols;
data.clear();
for(unsigned int i = 0; i < matrix.data.size(); i++) {
data.push_back(matrix.data[i]);
}
}
template <typename T>
void Matrix<T>::print() {
for(unsigned int i = 0; i < data.size(); i++) {
std::cout << data[i] << ", ";
if((i+1) % cols == 0)
std::cout << std::endl;
}
}
template <typename T>
Matrix<T> Matrix<T>::transpose() {
std::vector<T> vec;
for(unsigned int i = 0; i < data.size(); i++) {
vec.push_back(data[(cols*(i%rows)+i/rows)]);
}
return Matrix<T>(vec, cols, rows);
}
template <typename T>
Matrix<T> Matrix<T>::dot(const Matrix<typename std::remove_reference<T>::type> & rhs) {
if(cols != rhs.rows) {
std::cout << "Error! Can not resolve dot product on these matrices!" << std::endl;
std::cout << "Requested: [" << rows << "x" << cols << "] <alt+7> [" << rhs.rows << "x" << rhs.cols << "]" << std::endl;
Matrix<T> matrix;
return matrix;
}
Matrix<T> matrix;
return matrix;
}