Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > problems declaring operators in gcc

Reply
Thread Tools

problems declaring operators in gcc

 
 
Jim Michaels
Guest
Posts: n/a
 
      04-21-2007
friend fraction& operator+=(const fraction& rhs);

fraction.h(64) Error: error: 'fraction& operator+=(const fraction&)'
must take exactly two arguments


I practically pulled this out of a C++ book (except for the "friend").
can someone explain why GCC is giving me problems here?
for a += or similar operator, what does a proper declaration look like
and what are its arguments for?


fraction.h:64: error: 'fraction& operator+=(const fraction&)' must take
exactly two arguments
fraction.h:65: error: 'fraction& operator+=(const char*)' must have an
argument of class or enumerated type
fraction.h:65: error: 'fraction& operator+=(const char*)' must take
exactly two arguments
fraction.h:66: error: 'fraction& operator+=(const long int&)' must have
an argument of class or enumerated type
fraction.h:66: error: 'fraction& operator+=(const long int&)' must take
exactly two arguments
fraction.h:72: error: 'fraction& operator-=(const fraction&)' must take
exactly two arguments
fraction.h:73: error: 'fraction& operator-=(const char*)' must have an
argument of class or enumerated type
fraction.h:73: error: 'fraction& operator-=(const char*)' must take
exactly two arguments
fraction.h:74: error: 'fraction& operator-=(const long int&)' must have
an argument of class or enumerated type
fraction.h:74: error: 'fraction& operator-=(const long int&)' must take
exactly two arguments
fraction.h:80: error: 'fraction& operator*=(const fraction&)' must take
exactly two arguments
fraction.h:81: error: 'fraction& operator*=(const char*)' must have an
argument of class or enumerated type
fraction.h:81: error: 'fraction& operator*=(const char*)' must take
exactly two arguments
fraction.h:82: error: 'fraction& operator*=(const long int&)' must have
an argument of class or enumerated type
fraction.h:82: error: 'fraction& operator*=(const long int&)' must take
exactly two arguments
fraction.h:88: error: 'fraction& operator/=(const fraction&)' must take
exactly two arguments
fraction.h:89: error: 'fraction& operator/=(const char*)' must have an
argument of class or enumerated type
fraction.h:89: error: 'fraction& operator/=(const char*)' must take
exactly two arguments
fraction.h:90: error: 'fraction& operator/=(const long int&)' must have
an argument of class or enumerated type
fraction.h:90: error: 'fraction& operator/=(const long int&)' must take
exactly two arguments
fraction.h:96: error: 'fraction& operator%=(const fraction&)' must take
exactly two arguments
fraction.h:97: error: 'fraction& operator%=(const char*)' must have an
argument of class or enumerated type
fraction.h:97: error: 'fraction& operator%=(const char*)' must take
exactly two arguments
fraction.h:98: error: 'fraction& operator%=(const long int&)' must have
an argument of class or enumerated type
fraction.h:98: error: 'fraction& operator%=(const long int&)' must take
exactly two arguments
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      04-21-2007
Jim Michaels wrote:
> friend fraction& operator+=(const fraction& rhs);
>
> fraction.h(64) Error: error: 'fraction& operator+=(const fraction&)'
> must take exactly two arguments
>
>
> I practically pulled this out of a C++ book (except for the "friend").
> can someone explain why GCC is giving me problems here?
> for a += or similar operator, what does a proper declaration look like
> and what are its arguments for?
>

The error says it all, these operators require two arguments, the left
and right hand sides of the expression:

lhs += rhs.

--
Ian Collins.
 
Reply With Quote
 
 
 
 
Jim Michaels
Guest
Posts: n/a
 
      04-21-2007
Ian Collins wrote:
> Jim Michaels wrote:
>> friend fraction& operator+=(const fraction& rhs);
>>
>> fraction.h(64) Error: error: 'fraction& operator+=(const fraction&)'
>> must take exactly two arguments
>>
>>
>> I practically pulled this out of a C++ book (except for the "friend").
>> can someone explain why GCC is giving me problems here?
>> for a += or similar operator, what does a proper declaration look like
>> and what are its arguments for?
>>

> The error says it all, these operators require two arguments, the left
> and right hand sides of the expression:
>
> lhs += rhs.
>

friend fraction& operator~=(const fraction&, const fraction&); //no op
friend fraction& operator~=(const fraction&, const char *); //no op
friend fraction& operator~=(const fraction&, const long int&); // no op

fraction.h(12 Error: error: declaration of 'operator~' as non-function
fraction.h(129) Error: error: expected primary-expression before 'const'
fraction.h(129) Error: error: expected `)' before 'const'

I'm confused by the error messages. is this saying I'm supposed to do this?

friend fraction& operator~=(); //no op
friend fraction& operator~=(); //no op
friend fraction& operator~=(); // no op
then I get
fraction.h(12 Error: error: expected primary-expression before ')' token
fraction.h(12 Error: error: declaration of 'operator~' as non-function


I want to disable those operators. can I do that by just not using them?
--

------------------------------------
Jim Michaels
for email, edit the address

RAM Disk is *not* an installation method.
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      04-21-2007
Jim Michaels wrote:
> Ian Collins wrote:
>
>> Jim Michaels wrote:
>>
>>> friend fraction& operator+=(const fraction& rhs);
>>>
>>> fraction.h(64) Error: error: 'fraction& operator+=(const fraction&)'
>>> must take exactly two arguments
>>>
>>>
>>> I practically pulled this out of a C++ book (except for the "friend").
>>> can someone explain why GCC is giving me problems here?
>>> for a += or similar operator, what does a proper declaration look like
>>> and what are its arguments for?
>>>

>> The error says it all, these operators require two arguments, the left
>> and right hand sides of the expression:
>>
>> lhs += rhs.
>>

> friend fraction& operator~=(const fraction&, const fraction&); //no op
>
> I want to disable those operators. can I do that by just not using them?


There isn't an operator ~=.

--
Ian Collins.
 
Reply With Quote
 
Jim Michaels
Guest
Posts: n/a
 
      04-21-2007
Ian Collins wrote:
> Jim Michaels wrote:
>> Ian Collins wrote:
>>
>>> Jim Michaels wrote:
>>>
>>>> friend fraction& operator+=(const fraction& rhs);
>>>>
>>>> fraction.h(64) Error: error: 'fraction& operator+=(const fraction&)'
>>>> must take exactly two arguments
>>>>
>>>>
>>>> I practically pulled this out of a C++ book (except for the "friend").
>>>> can someone explain why GCC is giving me problems here?
>>>> for a += or similar operator, what does a proper declaration look like
>>>> and what are its arguments for?
>>>>
>>> The error says it all, these operators require two arguments, the left
>>> and right hand sides of the expression:
>>>
>>> lhs += rhs.
>>>

>> friend fraction& operator~=(const fraction&, const fraction&); //no op
>>
>> I want to disable those operators. can I do that by just not using them?

>
> There isn't an operator ~=.
>


fraction& operator+(const fraction& lhs, const fraction& rhs) {
mpq_add(frac, lhs.frac, rhs.frac);
return *this;
}

this is a friend function of the fraction class. for some reason, the
compiler chokes when I put this in the class definition.
it only works as a friend function. and now it complains
In function 'fraction& operator+(const fraction&, const fraction&)':
fraction.h(173) Error: error: 'frac' was not declared in this scope
fraction.h(174) Error: error: invalid use of 'this' in non-member function


I wish I could get it to work as a regular class member.


for a class member method (not template), what declaration would you use
for the following?
operator+, int as lhs, fraction as rhs, returning fraction
operator+, fraction as rhs, int as rhs, returning fraction
or am I totally misunderstanding the problem?

how would you overload unary + and -?

(I think maybe I can google this one, unless you know of a really good URL)
how would you overload << and >> for iostreams?

and for that, how do you output a char* kind of string to a stream?

------------------------------------
Jim Michaels
for email, edit the address

RAM Disk is *not* an installation method.
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      04-21-2007
Jim Michaels wrote:
>>

>
> fraction& operator+(const fraction& lhs, const fraction& rhs) {
> mpq_add(frac, lhs.frac, rhs.frac);
> return *this;
> }
>
> this is a friend function of the fraction class. for some reason, the
> compiler chokes when I put this in the class definition.


Because binary operator can't be class members, it would not make sense.

> it only works as a friend function. and now it complains
> In function 'fraction& operator+(const fraction&, const fraction&)':
> fraction.h(173) Error: error: 'frac' was not declared in this scope
> fraction.h(174) Error: error: invalid use of 'this' in non-member function
>

Exactly, only class members have a this pointer. You have to define a
temporary object, do the maths and return the temp.
>
> I wish I could get it to work as a regular class member.
>

Why, how would you use it?

>
> for a class member method (not template), what declaration would you use
> for the following?
> operator+, int as lhs, fraction as rhs, returning fraction
> operator+, fraction as rhs, int as rhs, returning fraction
> or am I totally misunderstanding the problem?
>

It looks like you are. A binary operator requires two parameters, the
lhs and rhs. Consider

c = a+b;

Which object does the operator modify? There isn't one, the operator
creates a new object which is the sum of a and b.

Now consider

a += b;

Here it is clear that a is the object being modified, so it does make
sense for the unary operator += to be a class member which requires one
parameter, the rhs.

> how would you overload unary + and -?
>


How would you define them? There isn't a unary operator + or -.

--
Ian Collins.
 
Reply With Quote
 
Mumia W.
Guest
Posts: n/a
 
      04-21-2007
On 04/20/2007 11:53 PM, Jim Michaels wrote:
>
> fraction& operator+(const fraction& lhs, const fraction& rhs) {
> mpq_add(frac, lhs.frac, rhs.frac);
> return *this;
> }
>
> this is a friend function of the fraction class. for some reason, the
> compiler chokes when I put this in the class definition.
> it only works as a friend function. and now it complains
> In function 'fraction& operator+(const fraction&, const fraction&)':
> fraction.h(173) Error: error: 'frac' was not declared in this scope
> fraction.h(174) Error: error: invalid use of 'this' in non-member function
>
>
> I wish I could get it to work as a regular class member.
>
>
> for a class member method (not template), what declaration would you use
> for the following?
> operator+, int as lhs, fraction as rhs, returning fraction
> operator+, fraction as rhs, int as rhs, returning fraction
> or am I totally misunderstanding the problem?
>


I doubt you can do that. Operator+ must only have one argument.


> how would you overload unary + and -?
> [...]


That's probably impossible too. I don't think that unary operator+ and
operator- exist.

As member functions, binary operator+ and operator- should work.

I'm not a C++ expert, but this should help you:


#include <cstdio>
#include <cstdlib>

class fraction {
int num;
int denom;

public:
fraction (int n = 0, int d = 1) : num(n), denom(d) { }

fraction & operator+(const fraction & other) {
fraction scopy = *this;
num = (scopy.num*other.denom + scopy.denom*other.num);
denom = scopy.denom * other.denom;
return *this;
}

char * c_str() {
char * temp = new char [20];
sprintf(temp,"%d/%d", num, denom);
return temp;
}

};



int main (void) {
int sp = 0;
char * strs[10];
char * string;

fraction fraa = fraction(12,3);
string = strs[sp++] = fraa.c_str();
puts(string);

fraction frab = fraa + fraction(1,3);
string = strs[sp++] = frab.c_str();
puts(string);

frab+1;
string = strs[sp++] = frab.c_str();
puts(string);

for (int n = 0; n < sp; n++) {
delete[] strs[n];
}
return 0;
}



 
Reply With Quote
 
Mumia W.
Guest
Posts: n/a
 
      04-21-2007
On 04/21/2007 03:39 AM, Mumia W. wrote:
> [...]
> fraction & operator+(const fraction & other) {
> fraction scopy = *this;
> num = (scopy.num*other.denom + scopy.denom*other.num);
> denom = scopy.denom * other.denom;
> return *this;
> }
> [...]


I apologize for the slightly non-intuitive behavior of my operator+
function. This is probably more to the norm:

fraction operator+(const fraction & other) {
fraction sf;
sf.num = (num*other.denom + denom*other.num);
sf.denom = denom * other.denom;
return sf;
}


 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      04-21-2007
On Apr 21, 7:22 am, Ian Collins <(E-Mail Removed)> wrote:
> Jim Michaels wrote:


> > fraction& operator+(const fraction& lhs, const fraction& rhs) {
> > mpq_add(frac, lhs.frac, rhs.frac);
> > return *this;
> > }


> > this is a friend function of the fraction class. for some reason, the
> > compiler chokes when I put this in the class definition.


> Because binary operator can't be class members, it would not make sense.


Since when? I regularly define binary operators are members.

It is usual for classes to define binary operators as free
functions in the case where the class supports implicit
conversions, so that the right hand operator supports the same
set of conversions as the left hand side, e.g. (supposing a
conversion of int to Decimal):

Decimal a,b,c ;
a = b + c ; // OK, global or member...
a = b + 1 ; // OK, global or member...
a = 1 + b ; // OK if global, not if member...

(Note that it is also usual in such cases to define += as a
member, and to define + in terms of +=, so that it doesn't even
need to be a friend.)

If the class in question doesn't have any converting
constructors (e.g. most iterators), then there's no real
argument against making the binary operators members (and my
iterators usually have operator==() and operator!=() as a
member).

And of course, some binary operators *must* be members---don't
forget that the assignment operator is a binary operator.

> > for a class member method (not template), what declaration would you use
> > for the following?
> > operator+, int as lhs, fraction as rhs, returning fraction
> > operator+, fraction as rhs, int as rhs, returning fraction
> > or am I totally misunderstanding the problem?


> It looks like you are. A binary operator requires two parameters, the
> lhs and rhs. Consider


> c = a+b;


> Which object does the operator modify? There isn't one, the operator
> creates a new object which is the sum of a and b.


> Now consider


> a += b;


> Here it is clear that a is the object being modified, so it does make
> sense for the unary operator += to be a class member which requires one
> parameter, the rhs.


There is no unary operator+=.

A binary operator may or may not be a member. If it is a
member, this points to the left argument, and it takes one
declared parameter for the right argument. If it is not a
member, it takes two parameters, the first for the left
argument, and the second for the right.

Special rules require that the binary operators = and [] be
members. (The n-ary operator () must also be a member.)

> > how would you overload unary + and -?


> How would you define them? There isn't a unary operator + or -.


Of course, there is. Generally, unary operators can be either
members, with this pointing to the argument, and no declared
parameters, or free functions, with a single declared parameter
for the argument. Again, some special rules: operator->,
operator& and operator* must be members, and post-fix operator++
and operator-- are declared as binary operators, with an int as
the second parameter. (The compiler will pass a 0 when they are
invoked using the operator syntax; normally, this value will be
ignored.)

(All of the above is from memory, so I may have missed some of
the special cases.)

--
James Kanze (Gabi Software) email: http://www.velocityreviews.com/forums/(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      04-21-2007
On Apr 21, 10:39 am, "Mumia W."
<(E-Mail Removed)> wrote:

[...]
> > I wish I could get it to work as a regular class member.


> > for a class member method (not template), what declaration would you use
> > for the following?
> > operator+, int as lhs, fraction as rhs, returning fraction
> > operator+, fraction as rhs, int as rhs, returning fraction
> > or am I totally misunderstanding the problem?


> I doubt you can do that. Operator+ must only have one argument.


Binary operator+ must have exactly two arguments. If it's a
member, the first is the implicit this argument, and only the
second is declared. If it's a free function, both must be
explicitly declared. Thus:

class MyClass
{
public:
// Either:
MyClass operator+( MyClass const& rhs ) const ;
} ;
// or:
MyClass operator+( MyClass const& lhs, MyClass const& rhs ) ;

For user defined arithmetic types (which typically support
conversion from int or double):

MyClass
operator+(
MyClass const& lhs,
MyClass const& rhs )
{
MyClass result( lhs ) ;
result += rhs ;
return result ;
}

is a classical implementation: operator+ is a free function, and
not even a friend. (Actually, they are often declared as
friends to allow the use of the Barton and Nackman trick. See
the documentation for the file Operators.hh in
http://kanze.james.neuf.fr/doc/en/Basic/html/index.html, for
example. But learn to overload operators correctly first;
this is a more or less advanced technique.)

Operators which modify the left operand, such as +=, are more
typically members.

> > how would you overload unary + and -?
> > [...]


> That's probably impossible too. I don't think that unary operator+ and
> operator- exist.


Are you kidding? (I've never actually used unary +, but unary
minus is frequent:
int minusOne = -1 ;
..)

> As member functions, binary operator+ and operator- should work.


Or as free functions. Single declared argument as a free
function, implicit this and no declared argument as a member.

> I'm not a C++ expert, but this should help you:
>
> #include <cstdio>
> #include <cstdlib>


> class fraction {
> int num;
> int denom;


> public:
> fraction (int n = 0, int d = 1) : num(n), denom(d) { }


> fraction & operator+(const fraction & other) {
> fraction scopy = *this;
> num = (scopy.num*other.denom + scopy.denom*other.num);
> denom = scopy.denom * other.denom;
> return *this;
> }


So:

1) operator+ actually has the semantics of +=, and not those of
+, and
2) "fraction( 1, 2 ) + 3" is legal, but "3 + fraction( 1, 2 )"
isn't (which is normal given 1).

Better:

fraction& operator+=( fraction const& other )
{
num = other.denom * num + denom * other.num ;
denom *= other.denom ;
return *this ;
}

(Except that you need some logic for renormalizing, and handling
the inevitable overflows.)

With a free function:

fraction
operator+( fraction const& lhs, fraction const& rhs )
{
fraction result( lhs ) ;
result += rhs ;
return result ;
}

(As it stands, I'd probably make this a friend, and construct
the return value immediately. But the above will leverage
automatically off the error checking and normalization in
operator+=, once it gets added.)

> char * c_str() {
> char * temp = new char [20];
> sprintf(temp,"%d/%d", num, denom);
> return temp;
> }


Never, never. You return a pointer, and count on the caller to
free it?

For such things, a friend
std:stream& operator<<( ostream& dest, fraction const& src) ;
is the normal solution.

--
James Kanze (Gabi Software) email: (E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Gcc 3.4.X to Gcc 4.1.X upgrading kas C++ 1 04-22-2010 08:56 PM
GCC 3.4.3 and GCC 4.1.2 ashnin C++ 1 07-07-2008 01:10 PM
Template construction in old gcc 3.3.3 does not compile in gcc 3.4.4 eknecronzontas@yahoo.com C++ 5 09-17-2005 12:27 AM
gcc 2.95 and gcc 3.2 gouqizi.lvcha@gmail.com C++ 8 03-16-2005 02:34 AM
C99 structure initialization in gcc-2.95.3 vs gcc-3.3.1 Kevin P. Fleming C Programming 2 11-06-2003 05:15 AM



Advertisments