Sign in to follow this  

Why only one of the operators is always called?

This topic is 1446 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Edited by Misery

Share this post


Link to post
Share on other sites

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.

Edited by Misery

Share this post


Link to post
Share on other sites


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.

Share this post


Link to post
Share on other sites
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. ;)

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

This topic is 1446 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this