简体   繁体   中英

c++ - copy constructor for template class

My class is a matrix composed out of vectors of vectors, and I seem to have problems in my constructor:

        #include <vector>
        #include <exception>
        #include <iostream>

        using namespace std;

       template<class T>
       class Matrix
       {
       private:

        unsigned int _rows;
        unsigned int _cols;
        vector <vector<T>> _matrix;

    public:

        const unsigned int INITIAL_ROW_SIZE = 1;
        const unsigned int INITIAL_COL_SIZE = 1;

        Matrix () : _rows(INITIAL_COL_SIZE), _cols(INITIAL_COL_SIZE),
                    _matrix(1,vector<T>(1))   {
            cout << "ctor" << endl;
        }

        Matrix (unsigned int rows, unsigned int cols) : _rows(rows), _cols(cols),_matrix(_rows,vector<T>(_cols)      { 
        }

  Matrix (const Matrix<T> &other) :Matrix(other._rows, other._cols)
    {
        for(int i = 0; i < _rows; i++)
        {
            copy(other._matrix[i].begin(), other._matrix[i].end(), _matrix[i]);
        }
        };
    }

the code will not compile when i try to use the copy constructor, as in Matric<int> m(5,5); Matrix<int> n=(m); Matric<int> m(5,5); Matrix<int> n=(m); because:

      In file included from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/vector:60:0,
                     from /cppex3/ex3/Matrix.hpp:8,
                     from /cppex3/ex3/Tester.cpp:6:
    /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algobase.h: In instantiation of '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = const std::vector<int, std::allocator<int> >*; _OI = std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >]':
    /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algobase.h:438:45:   required from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = __gnu_cxx::__normal_iterator<const std::vector<int, std::allocator<int> >*, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >; _OI = std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >]'
    /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algobase.h:471:8:   required from '_OI std::copy(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator<const std::vector<int, std::allocator<int> >*, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >; _OI = std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >]'
    /ex3/Matrix.hpp:42:13:   required from 'Matrix<T>::Matrix(const Matrix<T>&) [with T = int]'
  /ex3/Tester.cpp:25:20:   required from here
    /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algobase.h:394:57: error: no type named 'value_type' in '[01mstruct std::iterator_traits<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >'
           typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
                                                             ^
    /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algobase.h:399:9: error: no type named 'value_type' in 'struct std::iterator_traits<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >'
             && __are_same<_ValueTypeI, _ValueTypeO>::__value);
             ^

I suspect my initalization of the _matrix member is not correct, but I'm not sure. it could also by std::copy but the syntax seems correct.

Try with

copy(other._matrix[i].begin(), other._matrix[i].end(), 
     std::back_inserter(_matrix[i]));

or with

Matrix (const Matrix<T> &other)
   : _rows{other._rows}, _cols{other._cols}, _matrix{other._matrix}
 {
 }

Try this code, it works

Replace your

copy(other._matrix[i].begin(), other._matrix[i].end(), _matrix[i]);

with

copy(other._matrix[i].begin(), other._matrix[i].end(), _matrix[i].begin());

Below is the complete code.

#include <vector>
#include <exception>
#include <iostream>

using namespace std;

template<class T>
class Matrix
{
private:

    unsigned int _rows;
    unsigned int _cols;
    vector <vector<T> > _matrix;

public:

    Matrix () : _rows(1), _cols(1),
                _matrix(1,vector<T>(1))
    {
        cout << "ctor" << endl;
    }

    Matrix (unsigned int rows, unsigned int cols) : _rows(rows), _cols(cols)
    {
        _matrix=vector< vector<T> >(rows,vector<T>(cols));
    }


    Matrix (const Matrix<T> &other)
     : _rows{other._rows}, _cols{other._cols}, _matrix{other._matrix}
    {
        for(int i = 0; i < _rows; i++)
        {
            std::copy(other._matrix[i].begin(), other._matrix[i].end(), _matrix[i].begin());
        }
    }

};


int main(int argc, char const *argv[])
{
    Matrix<int> m(5,5);
    Matrix<int> n1(m);
    Matrix<int> n2(m);
    return 0;
}

Also

Matrix (const Matrix<T> &other) :Matrix(other._rows, other._cols);

replaced it with

Matrix (const Matrix<T> &other) {
    Matrix(other._rows, other._cols);
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM