overloading extraction operator << as friend of class to display list

Having trouble with this, my prototype looks like this

friend void operator<<(ostream& outs, const List& rhs);

and my function to implement looks like this, but whenever i try to run it i get an error saying "'void List::operator<<(std::ostream&, List&)' must take exactly one argument|"


1
2
3
4
5
6
7
8
9
10
11
void List::operator<<(ostream& outs, List& rhs){

    ListNode *cur = head;
    outs << cur->item << " ";

    for (int i = 0; i < getLength(); i++){
        cur = cur->next;
        outs << cur->item << " ";
        return outs;
    }
}


If i try to make it have one argument, then in my header file I get an error saying it must take exact two parameters, so i'm pretty confused, any help is appreciated
Maybe something like this...

prototype
 
    friend std::ostream & operator<<(std::ostream & outs, const List & rhs); 


definition
1
2
3
4
5
6
7
std::ostream & operator<<(std::ostream & outs, const List & rhs)
{  

    // put the required code here

    return outs;
}
In the definition above, operator<< takes 3 arguments. It takes a a pointer to List, a reference to ostream, and a reference to list.

Now, of course, you just read that and are thinking.. "It does not take a pointer to List! What's this bozo talking about?!" but, in fact, it does. Every member function of a class receives a pointer to the instance of the object it should be working on. You can access it as this within the member function. You don't use the rhs parameter anyway, so I assume you knew this on an intuitive level.

If you define operator << as a member of a class, the relative order of the parameters will be wrong.

For instance:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ostream&  List::operator<<(ostream& os ) // should be a const here.
{
    ListNode * cur = head ;
    // ...
    return os ;
}

int main()
{
    List list ;
    cout << list ;  // error, no match for overloaded operator<<.
    list << cout ;  // this works! but..  man, that just looks wrong!
    list.operator<<(cout) ;   // also works.
}


So, we come to the friend function. Note that member functions do not need to be friend functions, because they already have access to the internals of the class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  // friend declaration in List definition, then...

ostream& operator<<(ostream& os, const List & list)
{
    const ListNode * current = list.head ;
    while ( current )
    {
        os << current->item << " " ;
        current = current->next ;
        // if we did a return here, the loop would only execute one time.
    }

    // return when the loop is done.
    return os ;
}


Notice that the function is not a member of List, and now the parameters are in the correct order, so everything should work as we expect.
Last edited on
Now if i try to do that it tells me "ListNode was not declared in this scope"...I think that's why it needs to be friend?
If ListNode is defined in your List class you need to use List::ListNode.
so

List::ListNode ostream& operator<<(ostream& os, const List & list)

that's the header?
On line 5, the only place that ListNode was used in the snippet of code I gave above and doubtless where the error message your compiler gives pointed you to, you need to use List::ListNode so the line becomes:

const List::ListNode * current = list.head ;
thank you so much
Topic archived. No new replies allowed.