So, here's my problem in a nutshell: to optimize performance, I decided to store the matrix elements in a row-wise flat vector (std::vector<double> instead of std::vector<std::vector<double> >. I got it working the way I wanted it to be, I can access rows or columns and the iteration works just fine. After doing all of these, I decided that the performance of iteration would be improved further if I implement this matrix class in two variants, one row-wise (which has been implemented) and one column-wise so that I can use the latter when I need heavy calculations on different columns.

To implement such mechanics, I have tried to derive from the row-wise class and overload just those functions which define the element access operations. So, basically, I planned to have two classes which are exactly the same in interface and internal members, except for a few functions which have to be re-implemented to define the element retrieval. Here's the class declarations:

class matrix_base { public: matrix_base()=delete; matrix_base(const std::size_t&, const std::size_t&); matrix_base(const matrix_base&); matrix_base(const matrix_base&&); matrix_base& operator=(const matrix_base&); matrix_base& operator=(matrix_base&&); double& operator()(const std::size_t&, const std::size_t&); const double& operator()(const std::size_t&, const std::size_t&) const; //these two functions must be redefined by the derived class virtual iterator cbegin(const std::size_t&); virtual iterator rbegin(const std::size_t&); iterator begin(); void assign(std::initializer_list<double>); friend matrix_base operator+(const matrix_base&, const matrix_base&); friend matrix_base operator-(const matrix_base&, const matrix_base&); friend std::ostream& operator<<(std::ostream&, const matrix_base&); size_t row_count() const; //return the number of rows size_t col_count() const; //return the number of columns size_t size() const; protected: std::vector<double> _v; //a contiguous vector std::size_t _n; //number of rows std::size_t _m; //number of columns //convert between 2-index method and 1-index method virtual std::size_t linear_index(const std::size_t&, const std::size_t&) const; }; typedef matrix_base matrixrw; //just a typical second name for convenience, stands for row-wise matrix

Here's what I did for the derivation, which is problematic:

class matrixcw: public matrix_base { public: using matrix_base::matrix_base; //inherit base constructors, correct? iterator cbegin(const std::size_t&) override; iterator rbegin(const std::size_t&) override; protected: std::size_t linear_index(const std::size_t&, const std::size_t&) const override; };

As I expected, it should have worked out just fine but things are a little bit weird. The following works:

matrixrw a(2, 2), b(2, 2); a.assign({1,2,3,4}); b.assign({2,2,2,2}); matrixrw c{a+b};

But if I switch it to the derived class, there comes compilation errors.

matrixcw a(2, 2), b(2, 2); a.assign({1,2,3,4}); b.assign({2,2,2,2}); matrixcw c{a+b}; //generates compile errors!

Quote

\main.cpp||In function 'int main()':|

\main.cpp|14|error: no matching function for call to 'optimization::matrixcw::matrixcw(optimization::matrix_base)'|

\main.cpp|14|note: candidate is:|

\matrix.h|75|note: optimization::matrixcw::matrixcw(const size_t&, const size_t&)|

\matrix.h|75|note: candidate expects 2 arguments, 1 provided|

||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

I managed to narrow down the problem, it turns out that if I define operator+ for the derived class (an exact copy of the base version, just changing the types), everything works.

Why is this happening? Shouldn't it work if I don't redefine operator+?

*As a matter of fact, I would like to know if there are better approaches that I am not thinking of*