problems declaring operators in gcc

Discussion in 'C++' started by Jim Michaels, Apr 21, 2007.

  1. Jim Michaels

    Jim Michaels Guest

    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
     
    Jim Michaels, Apr 21, 2007
    #1
    1. Advertising

  2. Jim Michaels

    Ian Collins Guest

    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.
     
    Ian Collins, Apr 21, 2007
    #2
    1. Advertising

  3. Jim Michaels

    Jim Michaels Guest

    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(128) 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(128) Error: error: expected primary-expression before ')' token
    fraction.h(128) 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.
     
    Jim Michaels, Apr 21, 2007
    #3
  4. Jim Michaels

    Ian Collins Guest

    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.
     
    Ian Collins, Apr 21, 2007
    #4
  5. Jim Michaels

    Jim Michaels Guest

    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.
     
    Jim Michaels, Apr 21, 2007
    #5
  6. Jim Michaels

    Ian Collins Guest

    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.
     
    Ian Collins, Apr 21, 2007
    #6
  7. Jim Michaels

    Mumia W. Guest

    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;
    }
     
    Mumia W., Apr 21, 2007
    #7
  8. Jim Michaels

    Mumia W. Guest

    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;
    }
     
    Mumia W., Apr 21, 2007
    #8
  9. Jim Michaels

    James Kanze Guest

    On Apr 21, 7:22 am, Ian Collins <> 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:
    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
     
    James Kanze, Apr 21, 2007
    #9
  10. Jim Michaels

    James Kanze Guest

    On Apr 21, 10:39 am, "Mumia W."
    <> 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::eek:stream& operator<<( ostream& dest, fraction const& src) ;
    is the normal solution.

    --
    James Kanze (Gabi Software) email:
    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
     
    James Kanze, Apr 21, 2007
    #10
  11. Jim Michaels

    Ian Collins Guest

    James Kanze wrote:
    > On Apr 21, 7:22 am, Ian Collins <> 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.
    >

    Since I first miss-learned this many many years ago!

    Thanks for the correction.

    --
    Ian Collins.
     
    Ian Collins, Apr 21, 2007
    #11
  12. Jim Michaels

    Jim Michaels Guest

    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 ~=.
    >


    I think I have everything worked out now. thanks.

    --

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

    RAM Disk is *not* an installation method.
     
    Jim Michaels, Apr 22, 2007
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    8
    Views:
    432
  2. Kevin P. Fleming

    C99 structure initialization in gcc-2.95.3 vs gcc-3.3.1

    Kevin P. Fleming, Nov 6, 2003, in forum: C Programming
    Replies:
    2
    Views:
    646
    Kevin P. Fleming
    Nov 6, 2003
  3. Replies:
    5
    Views:
    362
    Nathan Addy
    Sep 17, 2005
  4. ashnin

    GCC 3.4.3 and GCC 4.1.2

    ashnin, Jul 7, 2008, in forum: C++
    Replies:
    1
    Views:
    524
    Michael DOUBEZ
    Jul 7, 2008
  5. kas
    Replies:
    1
    Views:
    319
    red floyd
    Apr 22, 2010
Loading...

Share This Page