Overloading << and its friends

Hey there, so I'm trying to overload the operator << as well as the basic arithmetic operations in a class Algebraic that I wrote. Sadly its not behaving as I expected. I wonder if anyone can see what I'm doing wrong.

So here's the definition of the operators:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ostream& operator <<(ostream& outputStream, Algebraic& num)
{
   \\CENSORED
  return outputStream;
}

Algebraic operator +(Algebraic a, Algebraic b)
{
  Algebraic c=a;
  return c+=b;
}

Algebraic& Algebraic::operator +=(Algebraic a)
{
  for(int i=0; i < coords.size(); i++)
    coords[i] += a.coords[i];
  return *this;
}

The definition of << is censored since it is very long and ugly (and doesn't seem relevant).

Now when I try to use these operators. here's what happens: Say I define a to be an Algebraic. Then
1
2
Algebraic b = a+a;
cout<<b<<"\n";

works as expected, but
 
cout<<a + a<<"\n";

produces a long error:
g++ -c -I. -I/usr/local/include -g hello.cc
hello.cc: In function ‘int main()’:
hello.cc:27: error: no match for ‘operator<<’ in ‘std::cout << operator+(Algebraic, Algebraic)(Algebraic(((const Algebraic&)((const Algebraic*)(& a)))))’
and several pages more ...

Anyone have any idea what I'm doing wrong? I can work around it with the first method but its kind of bugging me.
try cout<< (a + a) <<"\n";
Thanks for the quick reply! Actually I tried that already and get the same error.
Hmmm ok.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <string>

using namespace std;

class Foo {
public:
  Foo() { X = 3; }


  Foo operator +(Foo &b) {
    Foo C = Foo();
    C.X = X + b.X;
    return C;
  }
  operator int() { // use string if it's easier
    return X;
  }

  int X;
};

ostream& operator<<( ostream & out, Foo &b) {
  out << (int)b;
  return out;
}

int main() {

  Foo A = Foo();
  Foo B = A + A;

  cout << A << endl;
  cout << (A + A) << endl;

  return 0;
}


Close as I can get. Never been a fan of overloading << and >> myself :)
Last edited on
It is choking on the types of your arguments. The operator+ needs to take const reference args.

Algebraic operator +(const Algebraic& a, const Algebraic& b)

Likewise for your +=.

Hope this helps.
Thanks duoas. I tried changing both operators as you suggest, but I still get (nearly) the same error:hello.cc:26: error: no match for ‘operator<<’ in ‘std::cout << operator+(const Algebraic&, const Algebraic&)(((const Algebraic&)((const Algebraic*)(& c))))’
/usr/include/c++/4.2/ostream:112: note: candidates are: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>& (*)(std::basic_ostream<_CharT, _Traits>&)) yada yada yada ...

Probably its good to use references anyway for efficiency.

Zalta, thanks your code definitely works. I'll have to think about how to adapt it to my situation. I think your suggestion not to overload << is maybe the smartest suggestion of all.
Even with console apps I have never really overloaded it. I tend to add a print function or something similar. It usually just saves me headaches and makes the code a bit easier to read for other ppl :)
You made the ostream Algebraic const too, right?

I get no error with this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
using namespace std;

struct point
  {
  int x, y;
  point( int x = 0, int y = 0 ): x( x ), y( y ) { }
  point& operator += ( const point& p );
  };

point& point::operator += ( const point& p )
  {
  x += p.x;
  y += p.y;
  return *this;
  }

point operator + ( const point& a, const point& b )
  {
  point result = a;
  result += b;
  return result;
  }

ostream& operator << ( ostream& outs, const point& p )
  {
  outs << '(' << p.x << ',' << p.y << ')';
  return outs;
  }

int main()
  {
  point pt( 10, -7 );

  cout << pt << endl;
  cout << (pt + pt) << endl;

  return 0;
  }
Hmm... I didn't do that because it created about 20 other errors when I compiled. Let me try to fix them and see if it works.
It works! I can't believe it!!!!!
Thanks so much.


Glad to have helped.

The ticket is to remember that arguments to operators aren't necessarily pre-existing variables somewhere, or they may themselves be const, or implicitly type-promoted to something -- you just don't know what.

So they are always assumed to be constant references..
Topic archived. No new replies allowed.