Hi everyone,
I am having a problem while trying to do an operator overload of operator<<

I am getting:

Stack.cpp:96: `std::ostream& Stack::operator<<(std::ostream&, const Stack&)'
   must take exactly one argument
Stack.cpp:96: no `std::ostream& Stack::operator<<(std::ostream&, const Stack&)'
   member function declared in class `Stack'

I can't seem to find why I am getting this. Can anyone help me? Thank you in advance. Here is my code:

#include <iostream>
using namespace std;

#include "Stack.h"

Stack::Stack(void)
: _size(5), arr(new int[_size]), top(-1)
{
    ;;;
}

Stack::Stack(const Stack &s)
{
    copy(s);
}

Stack::~Stack(void)
{
    delete []arr;
}

void Stack::push(const int foo)
{
    if (top >= (_size -1))
    {
        int nsize = _size + 5;
        int *narr = new int[nsize];
        for (int i=0; i<=top; ++i)
        {
            narr[i] = arr[i];
        }
        delete []arr;
        _size = nsize;
        arr = narr;
    }
    arr[++top] = foo;
}

int Stack::pop(void)
{
    int rval = peek();
    --top;
    return rval;
}

int Stack::peek(void) const
{
    int rval = 0;

    if (empty())
    {
        cerr << "peek/pop when empty" << endl;
        exit(0);
    }
    else
    {
        rval = arr[top];
    }
    return rval;
}

int Stack::size(void) const
{
    return (top + 1);
}

bool Stack::empty(void) const
{
    return (top < 0);
}

void Stack::copy(const Stack &s)
{
    _size = s._size;
    top = s.top;
    arr = new int[_size];

    for(int i=0; i<=top; ++i)
    {
        arr[i] = s.arr[i];
    }
}


const Stack & Stack::operator= (const Stack &s)
{
 //   if (this != s)
 //   {
 //       delete []arr;
        copy(s);
 //   }
    return *this;
}

ostream & Stack::operator<< (ostream &ost, const Stack &s)
{
    for (int i=0; i<=s.top; ++i)
    {
        ost << s.arr[i] << ' ';
    }
    return ost;
}
#include <iostream>
using namespace std;
// template <class X>
class Stack
{
    private:
        int _size;
        int *arr;
        int top;
    public:
        Stack(void);
        ~Stack(void);
        Stack(const Stack &);
        void push(const int);
        int pop(void);
        int peek(void) const;
        int size(void) const;
        bool empty(void) const;
        void copy(const Stack &);
        const Stack & operator= (const Stack &);
        friend ostream & operator<< (ostream &, const Stack &);
        // bool operator!= (const Stack &) const;

};

operator<<() is a member function - you can only pass one parameter at a time to your Stack object using operator<<() - eg,

Stack myStackObj;
myStackObj << SomeValueHere;

If you are merely trying to overload operator<<() then it should be a non-member function.

When defined as a member, the object for which it is called is implicitly "this" (Just like any other member function). The same applies for the any other binary operators which you have defined as members of your stack - you only provide one argument because the "Left-Hand-Side" argument of a binary function is implicit.

Also, being a member function, there is no need for the 'friend' keyword.

Incidentally, and this is a style issue - if you create the operator as a member function, I think you should use operator>>() (I'll explain in a second...)

ostream & Stack::operator>> (ostream &ost)
{
    for (int i=0; i<=top; ++i)
    {
        ost << arr[i] << ' ';
    }
    return ost;
}

operator<<() is sometimes known as "put to", whereas operator>>() is respectively "get from"

You would be using your operator to "get" the data in arr[] "from" your Stack.

eg,

Stack MyStackObj;
// ..Populate MyStackObj here..
MyStackObj >> cout;

Continuing the conversation with myself... :)

Now that I've had some sleep, It's pretty clear that you don't want your operator<<() to be a member function of Stack, because the syntax to pass to cout is completely counter-intuitive, compared with the rest of STL. The "best" way is for you to make operator<<() a non-member function.

commented: Bench was a lot of help! +1

Thank you for your help. That was it. I had written this function before with other programs and I just did not notice that I had made it a member function. Thank you very much for your help!

How do you make it a non-member function? By putting before public and private?

using:
ostream &operator << (opstream &ost, const Stack &s)

instead of:
ostream & Stack::operator<< (ostream &ost, const Stack &s)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.