0

there is a Matrix implementation in C++ which follows the template expression pattern. I have to implement several type of operation such as addition, multiplication, etc. So I decided to create a base MatrixOperation template class with a pure virtual operator() which will do the actual trick of the operation. The Matrix class has an overloaded operator= for doing all the computations at assigment, and it class the Operation's operator(i,j).

The thing is that in Visual Studio 2013 this worked fine, but unfortunately I have to test it with gcc as well. And you can guess it, gcc does not like my solution.

To make it clear, here is the code:

template<class T, int N, int M>
class my_matrix {
    T data[N][M];
public:
    my_matrix() {}

    template<class Left, class Right>
    my_matrix<T, N, M>& operator=(const MatrixOperation<T, N, M, Left, Right>& right) { 
        for (int i = 0; i < N; ++i)
            for (int j = 0; j < M; ++j) 
                data[i][j] = right(i, j);
        return *this;
    }

    const T& operator()(int n, int m) const { return data[n][m];  }
    T& operator()(int n, int m) { return data[n][m]; }
};

/** MatrixOperation base class*/
template <class T, int N, int M, class Left, class Right>
class MatrixOperation {
protected:
    const Left& left;
    const Right& right;
public:
    MatrixOperation(const Left& lhs, const Right& rhs) : left(lhs), right(rhs) {}
    virtual T operator()(int n, int m) const = 0;
};

/** MatrixSum class */
template <class T, int N, int M, class Left, class Right>
class MatrixSum : public MatrixOperation<T, N, M, Left, Right> {
public:
    MatrixSum(const Left& lhs, const Right& rhs) : MatrixOperation<T, N, M, Left, Right>(lhs, rhs) {}
    T operator()(int n, int m) const { return left(n, m) + right(n, m); }
};

And what was the answer from the gcc? Something like this, just longer, this error repeated for all other operation.

g++ -Wall -c "Matrix.cpp"
Matrix.cpp: In member function ‘T MatrixSum<T, N, M, Left, Right>::operator()(int, int) const’:
Matrix.cpp:87:53: error: invalid initialization of reference of type ‘std::ios_base&’ from expression of type ‘int’
  T operator()(int n, int m) const { return left(n, m) + right(n, m); }
                                                     ^
In file included from /usr/include/c++/4.8/ios:42:0,
                 from /usr/include/c++/4.8/ostream:38,
                 from /usr/include/c++/4.8/iostream:39,
                 from Matrix.cpp:5:
/usr/include/c++/4.8/bits/ios_base.h:916:3: error: in passing argument 1 of ‘std::ios_base& std::left(std::ios_base&)’
   left(ios_base& __base)
   ^
Matrix.cpp:87:67: error: invalid initialization of reference of type ‘std::ios_base&’ from expression of type ‘int’
  T operator()(int n, int m) const { return left(n, m) + right(n, m); }
                                                                   ^
In file included from /usr/include/c++/4.8/ios:42:0,
                 from /usr/include/c++/4.8/ostream:38,
                 from /usr/include/c++/4.8/iostream:39,
                 from Matrix.cpp:5:
/usr/include/c++/4.8/bits/ios_base.h:924:3: error: in passing argument 1 of ‘std::ios_base& std::right(std::ios_base&)’
   right(ios_base& __base)
   ^

This error report is a bit unclear for me, so please, if you have any idea or suggestion do not hesitate to share with me. I a feeling that the problem comes from the inheritance and the base class. But without it I have to copy and paste a tons of code.

Thanks for any constructive answer!

Steve M. Bay
  • 313
  • 1
  • 3
  • 15
  • Are you using any C++11 feature and your G++ compiler is following the same C++ standard as MSVC++? – ha9u63a7 Nov 14 '14 at 21:32
  • 4
    Do you have `using namespace std` somewhere? – David G Nov 14 '14 at 21:33
  • I wrote the code in VS, and there was no problem. As far as I know, the MSVC++ does not following the standard, so it was not surprise for me, but I have to fix it. And yes, I have using namespace std. – Steve M. Bay Nov 14 '14 at 21:40
  • 2
    Since `MatrixOperation` is a dependent base class, you need to qualify the `left` and `right` members with `this->`. – David G Nov 14 '14 at 21:45

0 Answers0