Search code examples
c++matrixrvalue-referencemove-constructornullptr

"No viable overloaded =" nullptr


I have just started with C++ and am stuck on the move constructor. Here is my .cpp:

SimpleMatrix::SimpleMatrix(SimpleMatrix &&other_mat) {
 cols = other_mat.cols;
 rows = other_mat.rows;
 data_ = other_mat.data_;
 other_mat.cols = 0;
 other_mat.rows = 0;
 other_mat.data_ = nullptr; // <- Error here
}

I got No viable overloaded = error at other_mat.data_ = nullptr. What went wrong? Is it the way I initialize the matrix?

Here is the relevant parts in .hpp file:

class SimpleMatrix {
 public:
  SimpleMatrix(std::size_t nrows, std::size_t ncols);
  SimpleMatrix(std::initializer_list<std::initializer_list<double>> data);
  SimpleMatrix(SimpleMatrix&& other_mat);
  SimpleMatrix& operator=(SimpleMatrix&& other_mat);

 private:
  std::vector<std::vector<double> > data_;
  int rows, cols;
};

Solution

  • data_ is a vector non-pointer object, and nullptr is to initialize a pointer to be a null pointer.

    You can't assign non-pointer variables to be null pointers. And C++ doesn't have any concept of null values or objects.

    If you want the vector to be properly initialized I suggest you add a constructor initializer list:

    SimpleMatrix::SimpleMatrix(SimpleMatrix &&other_mat)
        : data_(std::move(other_mat.data_))  // Move the data from the other vector
        , rows(other_mat.rows)
        , cols(other_mat.cols)
    {
        // Clear the other matrix rows and cols
        other_mat.rows = 0;
        other_mat.cols = 0;
    }
    

    Or, you could rely on the rule of zero and let the compiler-generated constructors handle everything for you, which in this case it should do properly:

    class SimpleMatrix {
     public:
      SimpleMatrix(SimpleMatrix &&) = default;
      // ...
    };