ambiguous overload

O

onkar

#include<iostream>
using namespace std;
class Integer{
int i;
public:
Integer(int ii):i(ii){}
const Integer operator+(const Integer& rv){
cout<<"1-operator+"<<endl;
return Integer(i+rv.i);
}
Integer operator+=(Integer rv){
i+=rv.i;
cout<<"2-operator+="<<endl;
return *this;
}
friend Integer& operator+(Integer,Integer);

void display(){
cout<<"3-display()// i="<<i<<endl;
}
};
Integer& operator+(Integer rv,Integer rs ){
cout<<"2-operator+="<<endl;
rv.i+=rs.i;
return rv;
}
int main(void){
cout<<"buit-in types"<<endl;
int i=1,j=2,k=3;
k+=i+j;
cout<<"user defined types:"<<endl;
Integer ii(1),jj(2),kk(3);
kk+=ii+jj;
Integer d(1),b(2);
d=2+b;
d.display();
return 0;
}




g++ -g -Wall -o test test.cpp
test.cpp: In function 'Integer& operator+(Integer, Integer)':
test.cpp:22: warning: reference to local variable 'rv' returned
test.cpp: In function 'int main()':
test.cpp:33: error: ambiguous overload for 'operator+' in 'ii + jj'
test.cpp:7: note: candidates are: const Integer Integer::eek:perator+
(const Integer&)
test.cpp:22: note: Integer& operator+(Integer,
Integer)
make: *** [test] Error 1
??

What should I do to prevent this ??
 
I

Ian Collins

onkar said:
#include<iostream>
using namespace std;
class Integer{
int i;
public:
Integer(int ii):i(ii){}
const Integer operator+(const Integer& rv){
cout<<"1-operator+"<<endl;
return Integer(i+rv.i);
}
Integer operator+=(Integer rv){
i+=rv.i;
cout<<"2-operator+="<<endl;
return *this;
}
friend Integer& operator+(Integer,Integer);

void display(){
cout<<"3-display()// i="<<i<<endl;
}
};
Integer& operator+(Integer rv,Integer rs ){
cout<<"2-operator+="<<endl;
rv.i+=rs.i;
return rv;

You shouldn't return a reference to a local variable!
What should I do to prevent this ??

Stick to one operator+. Why have two?
 
O

onkar

You shouldn't return a reference to a local variable!


Stick to one operator+. Why have two?

#include<iostream>
using namespace std;
class Integer{
int i;
public:
Integer(int ii):i(ii){}
/* const Integer operator+(const Integer& rv){
cout<<"1-operator+"<<endl;
return Integer(i+rv.i);
} */
Integer operator+=(Integer rv){
i+=rv.i;
cout<<"2-operator+="<<endl;
return *this;
}
friend Integer& operator+(Integer,Integer);

void display(){
cout<<"3-display()// i="<<i<<endl;
}
};
Integer& operator+(Integer rv,Integer rs ){
cout<<"4-operator+"<<endl;
rv.i+=rs.i;
return rv;
}
int main(void){
cout<<"buit-in types"<<endl;
int i=1,j=2,k=3;
k+=i+j;
cout<<"user defined types:"<<endl;
Integer ii(1),jj(2),kk(3);
kk+=ii+jj;
Integer d(1),b(2);
d=2+b;
d.display();
return 0;
}



How to prevent this warning ??


g++ -g -Wall -o test test.cpp
test.cpp: In function 'Integer& operator+(Integer, Integer)':
test.cpp:22: warning: reference to local variable 'rv' returned

Note: If I remove & in
Integer& operator+(Integer rv,Integer rs )

g++ -g -Wall -o test test.cpp
test.cpp: In function 'Integer operator+(Integer, Integer)':
test.cpp:22: error: new declaration 'Integer operator+(Integer,
Integer)'
test.cpp:16: error: ambiguates old declaration 'Integer& operator+
(Integer, Integer)'
make: *** [test] Error 1

?? deadlocklike situation ?? :(
 
J

Jerry Coffin

[ ... ]
Integer& operator+(Integer rv,Integer rs ){
cout<<"4-operator+"<<endl;
rv.i+=rs.i;
return rv;
}

You're still returning a reference to a local variable. As much as you'd
like to return a reference to some existing variable, you really can't
-- you need to create and return a new instance. OTOH, you can pass one
of the parameters by reference (to const).

[ ... ]
Note: If I remove & in
Integer& operator+(Integer rv,Integer rs )

g++ -g -Wall -o test test.cpp
test.cpp: In function 'Integer operator+(Integer, Integer)':
test.cpp:22: error: new declaration 'Integer operator+(Integer,
Integer)'
test.cpp:16: error: ambiguates old declaration 'Integer& operator+
(Integer, Integer)'

The compiler is just telling you that this function body no longer
matches your friend declaration above, and the two (if there really were
two) would be ambiguous. You just need to make the friend declaration
and the function definition match each other. One way to do that is to
put them together:

class Integer {
// ...

friend Integer operator+(Integer rv, Integer rs) {
rv.i+=rs.i;
return rv;
}
};

Even though we've placed the body of the operator+ inside of the class
defintion, it is still a _global_ function, visible outside the class,
just as if its defintion were outside the class like you wrote it. FWIW,
this code is definitely open to further optimization (it creates at
least one more Integer object than necessary).
 
S

Salt_Peter

How to prevent this warning ??

g++ -g -Wall -o test test.cpp
test.cpp: In function 'Integer& operator+(Integer, Integer)':
test.cpp:22: warning: reference to local variable 'rv' returned

To prevent the warning, listen to the compiler. Acknowledge that rv, a
local variable, is destroyed once the function returns. You'll end up
with an invalid reference. One doesn't mail a letter to an address
that is about to cease to exist. Sounds silly because it is silly.

According to the statements you are showing in main(),
a) the only friend op i see would be:

friend Integer operator+(const int, const Integer&);

b) and a member function to add a primitive integer:

Integer& Integer::eek:perator+(const int n)
{
...
}
 
A

asterisc

#include<iostream>
using namespace std;
class Integer{
int i;
public:
Integer(int ii):i(ii){}
const Integer operator+(const Integer& rv){
cout<<"1-operator+"<<endl;
return Integer(i+rv.i);
}
Integer operator+=(Integer rv){
i+=rv.i;
cout<<"2-operator+="<<endl;
return *this;
}
friend Integer& operator+(Integer,Integer);

void display(){
cout<<"3-display()// i="<<i<<endl;
}};

Integer& operator+(Integer rv,Integer rs ){
cout<<"2-operator+="<<endl;
rv.i+=rs.i;
return rv;}

int main(void){
cout<<"buit-in types"<<endl;
int i=1,j=2,k=3;
k+=i+j;
cout<<"user defined types:"<<endl;
Integer ii(1),jj(2),kk(3);
kk+=ii+jj;
Integer d(1),b(2);
d=2+b;
d.display();
return 0;

}

g++ -g -Wall -o test test.cpp
test.cpp: In function 'Integer& operator+(Integer, Integer)':
test.cpp:22: warning: reference to local variable 'rv' returned
test.cpp: In function 'int main()':
test.cpp:33: error: ambiguous overload for 'operator+' in 'ii + jj'
test.cpp:7: note: candidates are: const Integer Integer::eek:perator+
(const Integer&)
test.cpp:22: note: Integer& operator+(Integer,
Integer)
make: *** [test] Error 1
??

What should I do to prevent this ??

For classes like the one designed by you, often is a good idea to
overload a conversion operator like "operator int();".
That way, you don't need to overload all the needed arithmetic
operators, relational operators, ...
 
S

siddhu

#include<iostream>
using namespace std;
class Integer{
        int i;
        public:
                Integer(int ii):i(ii){}
                const Integer operator+(const Integer& rv){
                        cout<<"1-operator+"<<endl;
                        return Integer(i+rv.i);
                }
                Integer operator+=(Integer rv){
                        i+=rv.i;
                        cout<<"2-operator+="<<endl;
                        return *this;
                }
                friend Integer& operator+(Integer,Integer);
                void display(){
                        cout<<"3-display()// i="<<i<<endl;
                }};
Integer& operator+(Integer rv,Integer rs ){
                        cout<<"2-operator+="<<endl;
        rv.i+=rs.i;
        return rv;}
int main(void){
         cout<<"buit-in types"<<endl;
        int i=1,j=2,k=3;
        k+=i+j;
        cout<<"user defined types:"<<endl;
        Integer ii(1),jj(2),kk(3);
        kk+=ii+jj;
        Integer d(1),b(2);
        d=2+b;
        d.display();
        return 0;

g++ -g -Wall -o test test.cpp
test.cpp: In function 'Integer& operator+(Integer, Integer)':
test.cpp:22: warning: reference to local variable 'rv' returned
test.cpp: In function 'int main()':
test.cpp:33: error: ambiguous overload for 'operator+' in 'ii + jj'
test.cpp:7: note: candidates are: const Integer Integer::eek:perator+
(const Integer&)
test.cpp:22: note:                 Integer& operator+(Integer,
Integer)
make: *** [test] Error 1
??
What should I do to prevent this ??

For classes like the one designed by you, often is a good idea to
overload a conversion operator like "operator int();".
That way, you don't need to overload all the needed arithmetic
operators, relational operators, ...- Hide quoted text -

- Show quoted text -

Better way to have only a friend operator+ function. Do not have
member fn. This way you can also do calcultions like
Integer I(1);
Integer J = 1 + I;

operator+ can be implemented in terms of operator+=. e.g.

friend const Integer(const Integer& I1,const Integer& I2)
{
Integer temp(I1);
temp += I2;
return temp;
}
 
V

Victor Bazarov

siddhu said:
#include<iostream>
using namespace std;
class Integer{
int i;
public:
Integer(int ii):i(ii){}
const Integer operator+(const Integer& rv){
cout<<"1-operator+"<<endl;
return Integer(i+rv.i);
}
Integer operator+=(Integer rv){
i+=rv.i;
cout<<"2-operator+="<<endl;
return *this;
}
friend Integer& operator+(Integer,Integer);
void display(){
cout<<"3-display()// i="<<i<<endl;
}};
Integer& operator+(Integer rv,Integer rs ){
cout<<"2-operator+="<<endl;
rv.i+=rs.i;
return rv;}
int main(void){
cout<<"buit-in types"<<endl;
int i=1,j=2,k=3;
k+=i+j;
cout<<"user defined types:"<<endl;
Integer ii(1),jj(2),kk(3);
kk+=ii+jj;
Integer d(1),b(2);
d=2+b;
d.display();
return 0;

g++ -g -Wall -o test test.cpp
test.cpp: In function 'Integer& operator+(Integer, Integer)':
test.cpp:22: warning: reference to local variable 'rv' returned
test.cpp: In function 'int main()':
test.cpp:33: error: ambiguous overload for 'operator+' in 'ii + jj'
test.cpp:7: note: candidates are: const Integer Integer::eek:perator+
(const Integer&)
test.cpp:22: note: Integer& operator+(Integer,
Integer)
make: *** [test] Error 1
??
What should I do to prevent this ??

For classes like the one designed by you, often is a good idea to
overload a conversion operator like "operator int();".
That way, you don't need to overload all the needed arithmetic
operators, relational operators, ...- Hide quoted text -

- Show quoted text -

Better way to have only a friend operator+ function. Do not have
member fn. This way you can also do calcultions like
Integer I(1);
Integer J = 1 + I;

operator+ can be implemented in terms of operator+=. e.g.

friend const Integer(const Integer& I1,const Integer& I2)

Probably meant to define it as

friend const Integer operator+(const Integer ....

although I am not sure why you want it to return a 'const'.
{
Integer temp(I1);
temp += I2;
return temp;
}

And the body could simply look like this

{
return Integer(I1.i + I2.i);
}

There is really no need to implement it in terms of +=, is there?

V
 
J

James Kanze

#include<iostream>
using namespace std;
class Integer{
int i;
public:
Integer(int ii):i(ii){}
/* const Integer operator+(const Integer& rv){
cout<<"1-operator+"<<endl;
return Integer(i+rv.i);
} */
Integer operator+=(Integer rv){
i+=rv.i;
cout<<"2-operator+="<<endl;
return *this;
}
friend Integer& operator+(Integer,Integer);

void display(){
cout<<"3-display()// i="<<i<<endl;
}};
Integer& operator+(Integer rv,Integer rs ){
cout<<"4-operator+"<<endl;
rv.i+=rs.i;
return rv;}
int main(void){
cout<<"buit-in types"<<endl;
int i=1,j=2,k=3;
k+=i+j;
cout<<"user defined types:"<<endl;
Integer ii(1),jj(2),kk(3);
kk+=ii+jj;
Integer d(1),b(2);
d=2+b;
d.display();
return 0;
}
How to prevent this warning ??
g++ -g -Wall -o test test.cpp
test.cpp: In function 'Integer& operator+(Integer, Integer)':
test.cpp:22: warning: reference to local variable 'rv' returned

Read the text of the warning. It's quite clear. The obvious
way to avoid a warning "reference to local variable 'rv'
returned" is to not return a reference to the local variable
'rv', no?

In general, you shouldn't ever return a reference to a local
variable, since there's no way the client can use that reference
without incurring undefined behavior.
Note: If I remove & in
Integer& operator+(Integer rv,Integer rs )
g++ -g -Wall -o test test.cpp
test.cpp: In function 'Integer operator+(Integer, Integer)':
test.cpp:22: error: new declaration 'Integer operator+(Integer,
Integer)'
test.cpp:16: error: ambiguates old declaration 'Integer& operator+
(Integer, Integer)'
make: *** [test] Error 1

Of course. All of the declarations have to be identical. If
you remove it in one declaration, you have to remove it in all.
 
J

James Kanze

#include<iostream>
using namespace std;
class Integer{
int i;
public:
Integer(int ii):i(ii){}
const Integer operator+(const Integer& rv){
cout<<"1-operator+"<<endl;
return Integer(i+rv.i);
}
Integer operator+=(Integer rv){
i+=rv.i;
cout<<"2-operator+="<<endl;
return *this;
}
friend Integer& operator+(Integer,Integer);
void display(){
cout<<"3-display()// i="<<i<<endl;
}};
Integer& operator+(Integer rv,Integer rs ){
cout<<"2-operator+="<<endl;
rv.i+=rs.i;
return rv;}
int main(void){
cout<<"buit-in types"<<endl;
int i=1,j=2,k=3;
k+=i+j;
cout<<"user defined types:"<<endl;
Integer ii(1),jj(2),kk(3);
kk+=ii+jj;
Integer d(1),b(2);
d=2+b;
d.display();
return 0;

g++ -g -Wall -o test test.cpp
test.cpp: In function 'Integer& operator+(Integer, Integer)':
test.cpp:22: warning: reference to local variable 'rv' returned
test.cpp: In function 'int main()':
test.cpp:33: error: ambiguous overload for 'operator+' in 'ii + jj'
test.cpp:7: note: candidates are: const Integer Integer::eek:perator+
(const Integer&)
test.cpp:22: note: Integer& operator+(Integer,
Integer)
make: *** [test] Error 1
??
What should I do to prevent this ??

For classes like the one designed by you, often is a good idea to
overload a conversion operator like "operator int();".
That way, you don't need to overload all the needed arithmetic
operators, relational operators, ...
 
J

James Kanze

siddhu wrote:

[...]
Probably meant to define it as
friend const Integer operator+(const Integer ....
although I am not sure why you want it to return a 'const'.

To prevent things like:
Integer i, j, k ;
(i + j) = k ;
I've read (in Scott Meyers, I think) that this is a good idea.
Abstractly, I think it's a good idea. In practice, I've never
bothered; the type of error it prevents doesn't seem to occur in
practice anyway.
And the body could simply look like this
{
return Integer(I1.i + I2.i);
}
There is really no need to implement it in terms of +=, is there?

In such a simple case as this, no. It's the idiomatic solution,
however---normally, if you're doing much of this sort of thing,
you'll actually defined such operations in a templated base
class, so all you have to do is derive, e.g.:

template< typename T >
class ArithmeticOperators
{
friend T operator+( T const& lhs, T const& rhs )
{
T result( lhs ) ;
result += rhs ;
return result ;
}
// The same for all of the arithmeitc operators...
} ;

class BigInteger : private ArithmeticOperators< BigInteger >
{
public :
// ...
BigInteger& operator+=( BigInteger const& other ) ;
// ...
} ;

It saves a lot of typing, and positively guarantees that + will
have the same semantics as +=. (And if you've misunderstood the
requirements, and implemented the wrong semantics, you only have
to change the code at one place.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top