#include <vector>

template <typename T>
class matrix 
{
  std::size_t    mRowdim, mColdim;
  std::vector<T> mValues;

public:
  matrix(std::size_t rowdim, std::size_t coldim) 
    : mRowdim(rowdim), mColdim(coldim), mValues(rowdim*coldim) {} // rowdim x coldim matrix 

  matrix(const matrix& other) 
    : mRowdim(other.mRowdim), mColdim(other.mColdim), mValues(other.mValues) {} // copy ctor

  matrix(matrix&& other) 
    : mRowdim(other.mRowdim), mColdim(other.mColdim), mValues(std::move(other.mValues)) {} // move ctor

  matrix &operator= (const matrix &other) // copy operator
  {
    matrix other_cpy(other);
    other_cpy.swap(*this);
    return *this;
  }

  matrix &operator= (matrix &&other) // move operator
  {
     other.swap(*this);
     return *this;
  }
 
  void swap(matrix &other) // swaperator
  { 
    std::swap(mRowdim, other.mRowdim);
    std::swap(mColdim, other.mColdim);
    mValues.swap(other.mValues); 
  }

  T &operator() (std::size_t row, std::size_t col)
  {
    return mValues[mColdim*row + col];
  } 

  const T &operator() (std::size_t row, std::size_t col) const
  { 
    // ... range check ...
    return mValues[mColdim*row + col];
  } 
};

int main()
{
  matrix<double> my_matrix(10,10);

  return 0;
}