Перегруженный оператор присваивания с массивами

#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 .