Why only one of the operators is always called?

Started by
7 comments, last by Aardvajk 10 years, 3 months ago

Hello,

I have two operators, one returning a value


int operator()(int i) const

and second allowing to get the reference of a value (to write it):


int& operator()(int i)

And the problem is that no matter what always the second operator is called. Shouldn't it be called only when reference is needed?

I have written a simple class illustrating my problem:


#include <iostream>

class Test
{
private:
    int tab[10],N;

public:
    Test()
    {
      N=10;
      for (int i=0;i<N;i++) tab[i]=i;
    }

    int operator()(int i) const
    {
      std::cout<<"why am i never called?"<<std::endl;
      return tab[i];
    }

    int& operator()(int i)
    {
      std::cout<<"why am i always called?"<<std::endl;
      return tab[i];
    }
};

And the following code demonstrates the issue:


	Test a;
	int b=a(1);  //uses the &operator
        a(2); //uses the &operator
        a(3)=8; //uses the &operator

I'll be grateful for any suggestions.

Advertisement

The const-version of the operator would only be called on a const instance.

The const-version of the operator would only be called on a const instance.

But when there is no


int& operator()(int i)

then the


int operator()(int i) const

is called. Of course then I can only read an element. Is there any way to use both of those operators, dependently on the context?

Thank you for your reply.


Shouldn't it be called only when reference is needed?
As a general rule of thumb, pretend that the type of the return value is ignored when determining which overload will be called.

Yep, it would be nice a lot of the time if the language looked at how you used the return value, and then picked the most appropriate overload... but that's not how it works. Instead it looks at the arguments (including whether this is const or not) to determine which overload to call, and then you get given a particular return type depending on that choice.

Thanks for answers. I'll just write one more reference class to manage.

Why is this a problem?

What I don't get is why Hodgeman thinks that "it would be nice" to have context-aware evaluation. Perl has a tiny bit of it (scalar -vs- list context) and it is rather confusing. The first page about it I found online has this:

$a = 6, 1, 1, 1, 7; say $a; # 6
$a = (6, 1, 1, 1, 7); say $a; # 7
@a = (6, 1, 1, 1, 7); $a = @a; say $a; # 5
C++ is confusing enough, thank you. ;)

By default C++ utilizes operator overloading in operation chaining. Thats why it prefers the method, returning l-value. Temporal objects cannot be l-values.

By default C++ utilizes operator overloading in operation chaining. Thats why it prefers the method, returning l-value. Temporal objects cannot be l-values.

That has nothing to do with why it prefers the non-const method. It prefers it because the object it is called on isn't const.

This topic is closed to new replies.

Advertisement