Hi all. Maybe my question is somewhat basic, I apologize in the case. I have coded the usual class for matrix manipulation. Following an example, I wrote:
1 2 3 4 5
T& operator()(std::size_t row, std::size_t column)
{
if (not(row < nR and column < nC)) throw"ERROR operator()";
return v[nC*row+column];
}
which permits to access the private vector v, inside the class, with a two indices notation (i,j). Then I have, say,:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
unique_ptr<matrix<T>> operator*(matrix<T> & m)
{
if (nC != m.sizeR()) throw"ERROR operator*";
unique_ptr<matrix<T>> result(new matrix<T>(nR, m.sizeC()));
for (size_t r=0; r<nR; r++)
for (size_t c=0; c<m.sizeC(); c++)
{
for (size_t k=0; k<nC; k++)
{
(*result)(r,c) += (*this)(r,k) * m(k,c);
}
}
return result;
}
Everything works fine, but I don't understand why it doesn't compile if I declare:
1 2 3 4 5 6 7 8
unique_ptr<matrix<T>> operator*(matrix<T> & m) const
{
// ...
// error:
// passing 'const matrix<double>' as 'this' argument of 'T& matrix<T>::operator()
// (std::size_t, std::size_t) [with T = double; std::size_t = unsigned int]'
// discards qualifiers [-fpermissive])
or if I declare
1 2 3 4 5 6 7 8
unique_ptr<matrix<T>> operator*(matrix<T> const& m)
{
// ...
// error:
// passing 'const matrix<double>' as 'this' argument of 'size_t matrix<T>::sizeR()
// [with T = double; size_t = unsigned int]'
// discards qualifiers
Your operator() is not const, so you cannot call it on a non-const matrix. You may want to make another version of your operator() that is const and returns a const reference.
Thank you Zhuge, I'm starting understanding the problem. On the other hand, to use the operator() so that I can assign a value to the element of the matrix...
mx(3,5) = 12.34;
...operator() must be non-const, or am I wrong? hence operator* must stay non-const too, is it right?
this is another surprise. I thought that the operator functions couldn't be overloaded within a class! Thank you so much NT3 (& Zhuge: only now I have understood what you meant!).
---
I did this way
You can overload an operator with whatever types you like, if that is what you are asking. They are exactly the same as functions - it just so happens that there are 'shortcut' ways of calling them. Here is a good little bunch of questions and answers on operator overloading which should help get you sorted: http://isocpp.org/wiki/faq/operator-overloading
Thank you NT3. In the recent past I have tried to overload some operator functions, but the compiler gave me some errors. I thought wrongly that it wasn't allowed to overload them, and I didn't study the issue further, silly of me.
---
Said that, I still don't understand why I cannot compile my class if I declare the passed matrix as 'const'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
unique_ptr<matrix<T>> operator*(matrix<T> const& m) const
{
if (nC != m.sizeR()) throw"ERROR operator*";
unique_ptr<matrix<T>> result(new matrix<T>(nR, m.sizeC()));
for (size_t r=0; r<nR; r++)
for (size_t c=0; c<m.sizeC(); c++)
{
for (size_t k=0; k<nC; k++)
{
(*result)(r,c) += (*this)(r,k) * m(k,c);
}
}
return result;
}
Ah, I see now - this operator doesn't appear to be part of the matrix class you specified. The errors will be using 'const' on a non-class function. Add it in to the class you want it to be part of: