Jump to content

  • Log In with Google      Sign In   
  • Create Account


Why only one of the operators is always called?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
8 replies to this topic

#1 Misery   Members   -  Reputation: 247

Like
0Likes
Like

Posted 28 December 2013 - 06:40 AM

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, 28 December 2013 - 06:43 AM.


Sponsor:

#2 BitMaster   Crossbones+   -  Reputation: 3048

Like
3Likes
Like

Posted 28 December 2013 - 06:50 AM

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



#3 Misery   Members   -  Reputation: 247

Like
0Likes
Like

Posted 28 December 2013 - 06:55 AM

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, 28 December 2013 - 06:57 AM.


#4 Hodgman   Moderators   -  Reputation: 24222

Like
3Likes
Like

Posted 28 December 2013 - 07:01 AM


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.



#5 Misery   Members   -  Reputation: 247

Like
0Likes
Like

Posted 28 December 2013 - 11:09 AM

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

#6 SiCrane   Moderators   -  Reputation: 9158

Like
0Likes
Like

Posted 28 December 2013 - 12:44 PM

Why is this a problem?



#7 Álvaro   Crossbones+   -  Reputation: 10820

Like
1Likes
Like

Posted 28 December 2013 - 01:01 PM

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. ;)

#8 GuardianX   Crossbones+   -  Reputation: 1381

Like
0Likes
Like

Posted 28 December 2013 - 02:49 PM

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



#9 Aardvajk   Crossbones+   -  Reputation: 4200

Like
0Likes
Like

Posted 28 December 2013 - 03:26 PM

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.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS