-1

I've received an excercise to implement a generic Matrix class. One of the tasks is as follows: "Overload operator() which gets parameterse (unsigned int, unsigned int) twice, once as const and once as a non-const.".

Now, after much searching, I understood that this should be how their signatures:

    T operator()(unsigned int rows, unsigned int colls) const; //cout << "A" << endl;
    T & operator()(unsigned int rows, unsigned int colls); //cout << "B" << endl;

however, no matter which way I'm trying to call them only the second one is called:

    int main()
    {
        Matrix<int> mat(2, 3);
        mat(1, 1) = 3;
        int i= (9 + mat(1, 1)) ;
        i = mat(2, 1);
        cout << i << endl;
        if (i == mat(1, 2)) {}
        int j = Matrix<int>(2, 2)(1, 1); //calls constructor and then subscription.
    }

The output will be:

B
B
B
0
B
B
theroyn
  • 125
  • 1
  • 11
  • There's no reason for your code to invoke the CV qualified version of the function because the instance of `Matrix` are `const` or rvalues. Change your `Matrix` variable to `const` and it'll get called. – Captain Obvlious Sep 10 '15 at 23:09
  • Try something like `int x = Matrix(2, 3);` – πάντα ῥεῖ Sep 10 '15 at 23:11
  • @πάντα ῥεῖ just tried and it doesn't changeanything. – theroyn Sep 10 '15 at 23:17
  • @Captain Obvlious What i understood is that the whole point of overloading twice is that one will be for rvalues? If I'll change the variable to const indeed it will get called, but then why not for rvalues? or maybe I just didn't understand the task properly? – theroyn Sep 10 '15 at 23:20

1 Answers1

2

Good on the instructor for requesting operator(). There is hope for the universe.

This isn't so much of an rvalue/lvalue thing as it is constant/non constant. The const on the end of the method definition states (and the compiler will do a and does a reasonable level checking that it won't) that calls to the method will not change the object's state. Absolutely necessary if you want to be able to call methods on a constant object.

If you add the following function to your test code:

void consttest(Matrix<int> &mat, const Matrix<int> &cmat)
{
    mat(1,1) =4;
    cmat(1,1) =4;
}

And call it like this:

consttest(mat, mat);

You'll see that good ol' rvalue/lvalue stuff in action. Sadly, you won't get to see your see your const operator() getting called because it won't compile. Pretty good test in it's own way, the method is guarded pretty well from mistakes, but a more useful test for functionality is:

void consttest(Matrix<int> &mat, const Matrix<int> &cmat)
{
    std::cout << mat(1,2) << std::endl;
    std::cout << cmat(1,2) << std::endl;
}

By the way, here's a nice chat on lvalues and rvalues: What are rvalues, lvalues, xvalues, glvalues, and prvalues?

Community
  • 1
  • 1
user4581301
  • 29,019
  • 5
  • 26
  • 45