#arrays #class #c 11 #templates #operator-overloading
Вопрос:
Моя цель-суметь это сделать:
#include "rMatrix.h"
int main() {
rMatrix<double> testMat1;
rMatrix<double> testMat2;
int td1[] = {1,2,3,4};
int td2[] = {1,2,3,4};
testMat1 = td1;
testMat2 = td2;
}
К сожалению, мои усилия не увенчались успехом. Matrix.h приведен ниже для справки, а также сообщение об ошибке.
Попытки включают:
- удаление
template <class U>
обозначения для преобразования типа. - удаление
template <std::size_t N>
и изменение наconst T (amp;RHS)[]
. - удаление [] заставляет меня переходить к тому,
testMat1 = *td1
что я нахожу неоптимальным
1>e:documentsvisual studio 2012проектыnntestnntestrmatrix.h(26): ошибка C3857: ‘rMatrix::оператор =’: несколько списков параметров шаблона не допускаются 1>> e:documentsvisual studio 2012проектыnntestnntestrmatrix.h(31) : см. ссылку на создание экземпляра шаблона класса «rMatrix», который компилируется 1>>>e:documentsvisual студия 2012проектыnntestnntestrматрица.ч(102): ошибка ошибка c2244: ‘rMatrix::оператор =’ : не удается сопоставить определение функции с существующим объявлением 1> Определение 1> ‘rMatrix amp;rMatrix::оператор =(const и у (amp;)[Н])’ 1> существующий заявления 1> ‘rMatrix amp;rMatrix::оператор =(const и у (amp;)[Н])’ 1> ‘rMatrix amp;rMatrix::оператор =(rMatrix константный amp;)’1>e:documentsvisual студия 2012проектыnntestnntestrmatrix.ч(26): ошибка C3857: ‘rMatrix::оператор =’: множественный шаблон параметр списки не допускается 1> с 1> [ 1> T=с поплавковым 1>
] 1> e:documentsvisual студия 2012projectsnntestnntestsource.cpp(12) : см. ссылку на экземпляр шаблона класса ‘rMatrix быть компилируется 1> с 1> [ 1> T=с поплавковым 1> ] 1>e:documentsvisual студия 2012проектыnntestnntestrmatrix.ч(26): ошибка C3857: ‘rMatrix::оператор =’: множественный шаблон параметр списки не допускается 1> с 1> [ 1> Т=1 двуспальной>
] 1> e:documentsvisual студия 2012projectsnntestnntestsource.cpp(13) : см. ссылку на создание экземпляра шаблона класса ‘rMatrix’, который компилируется 1>> с 1>>> [ 1>>>> T=двойной 1>>>>> ] 1>>>>>>e:documentsvisual студия 2012projectsnntestnntestsource.cpp(19): ошибка C2679: двоичный ‘=’ : не найден оператор, который принимает правый операнд типа ‘int [4]’ (или нет приемлемого преобразования) 1>>>>>>> > e:documentsvisual студия 2012проектыnntestnntestrmatrix.h(24): может быть ‘rMatrix amp;rMatrix::оператор =(константа rMatrix amp;)’ 1>>>>>>>> с 1>>>>>>>>>
[ 1> T=с поплавковым 1> ] 1> при попытке сопоставить список аргументов ‘(rMatrix, тип int [4])’ 1> с 1>
[ 1> T=с поплавковым 1> ] 1>e:documentsvisual студия 2012projectsnntestnntestsource.cpp(20): ошибка C2679: двоичный ‘=’ : оператор не найден, который принимает правый операнд типа ‘int [4]’ (или нет приемлемого преобразования) 1> e:documentsvisual студия 2012проектыnntestnntestrmatrix.ч(24): может быть ‘rMatrix amp;rMatrix::оператор =(rMatrix слово const amp;)’ 1> с 1>
[ 1> т=двухместная 1> ] 1> при попытке сопоставить список аргументов ‘(rMatrix, тип int [4])’ 1> с 1>
[ 1> т=двухместная 1> ] 1> 1>сбой построения.
«rMatrix.h»
#include <algorithm>
template <class T>
class rMatrix {
private:
T* data;
int colN;
int rowN;
public:
rMatrix();
rMatrix(unsigned int size);
rMatrix(int row,int col);
rMatrix(const rMatrixamp; mat);
~rMatrix();
T iloc(int index);
T iloc(int row, int col);
rMatrix<T>amp; operator=(const rMatrix amp; RHS);
template <class U>
template <std::size_t N>
rMatrix<T>amp; operator=(const U (amp;RHS)[N]);
void reshape(int row,int col);
};
template <class T>
rMatrix<T>::rMatrix() : rowN(0), colN(0), data(NULL) {}
template <class T>
rMatrix<T>::rMatrix(const rMatrix<T> amp; mat) {
if (data != NULL) {
data = new T[mat.rowN*mat.colN];
std::copy(std::begin(mat.data),std::end(mat.data),std::begin(data));
}
rowN = mat.rowN;
colN = mat.colN;
}
template <class T>
rMatrix<T>::rMatrix(unsigned int size) : rowN(size), colN(1) {
data = new T[size];
for(unsigned int i = 0; i < size; i ) {
data[i] = 0;
}
}
template <class T>
rMatrix<T>::rMatrix(int row, int col) : rowN(row), colN(col) {
unsigned int size = row*col;
data = new T[size];
for(unsigned int i = 0; i < size; i ) {
data[i] = 0;
}
}
template <class T>
rMatrix<T>::~rMatrix() {
if (data != NULL) {
delete [] data;
}
data = NULL;
colN = 0;
rowN = 0;
}
template <class T>
T rMatrix<T>::iloc(int index) {
return data[index];
}
template <class T>
T rMatrix<T>::iloc(int row, int column) {
return this->loc(row column * rowN);
}
template <class T>
rMatrix<T>amp; rMatrix<T>::operator=(const rMatrix amp; RHS) {
rowN = RHS.rowN;
colN = RHS.colN;
data = new T[rowN*colN];
for(unsigned int i = 0; i < unsigned int(rowN*colN); i ) {
data[i] = RHS.data[i];
}
//std::copy(std::begin(RHS.data), std::end(RHS.data), std::begin(data));
return *this;
}
template <class T> //, std::size_t N>
template <class U>
template <std::size_t N>
rMatrix<T>amp; rMatrix<T>::operator=(const U (amp;RHS) [N]) {
std::copy(std::begin(RHS),std::end(RHS),std::begin(data));
return *this;
}
Решенный
#include <algorithm>
template <class T>
class rMatrix {
private:
T* data;
int colN;
int rowN;
public:
rMatrix();
rMatrix(unsigned int size);
rMatrix(int row,int col);
rMatrix(const rMatrixamp; mat);
~rMatrix();
T iloc(int index);
T iloc(int row, int col);
rMatrix<T>amp; operator=(const rMatrix amp; RHS);
template <class U, std::size_t N>
rMatrix<T>amp; operator=(const U (amp;RHS)[N]);
void reshape(int row,int col);
};
/*** Other Functions ***/
template <class T> //, std::size_t N>
template <class U, std::size_t N>
rMatrix<T>amp; rMatrix<T>::operator=(const U (amp;RHS) [N]) {
rowN = N;
colN = 1;
data = new T[N];
for(unsigned int i = 0; i < unsigned int(rowN*colN); i )
data[i] = static_cast<T>(RHS[i]);
return *this;
}
Комментарии:
1. Чего
template <class U>
мы должны достичь? Особенно, когда ваша декларацияrMatrix<T>amp; operator=(const T (amp;RHS)[N]);
—U
не используется.2. Упс, много чего менял и забыл переключить это обратно перед публикацией. Хех, извини. Исправил это. На второй ноте я думаю, что это должно что-то сделать в духе Matrix<float> = int[] в моем уме. Может быть, я делаю это сложнее, чем должно быть.
Ответ №1:
Компилятор говорит вам о первой проблеме: не должно быть 2 строк шаблона, если вы хотите, чтобы U и N выглядели так:
template <typename U, std::size_t N>
rMatrix<T>amp; operator=(const U (amp;RHS)[N]) ;
Однако для упрощения попробуйте сначала это:
template < std::size_t N>
rMatrix<T>amp; operator=(const int (amp;RHS)[N]) ;
Я думаю, что это все равно не сработает. Я считаю, что массивы передаются как указатели, даже если вы объявляете параметр с размером. Но все равно попробуйте, я могу ошибиться.
Если я прав, то тебе не повезло. Вам нужно ожидать значения в виде указателя с дополнительным параметром count или переключиться на std::массив.
Комментарии:
1. Ах, спасибо за совет! Решил проблему. Пришлось немного переписать вторую часть, но это сработало…
2. Это научило меня кое-чему очень полезному! Я убрал параметры массива как бесполезные в своем мозгу, потому что, на мой взгляд, их использование в качестве указателя противоречит их назначению. Я не знал, что передача их в качестве ссылки на самом деле заставляет их работать так, как я изначально ожидал. Я предполагаю, что это способ C сделать функцию полезной при сохранении совместимости C.
3. забавно то, что … в конце концов, если я просто не передам это как константу, я смогу использовать
int (amp;RHS)
без необходимости что-либо менять в интерфейсеmatrix = array
.