1

Here's my code:

template<typename T>
class list {                                               
    private:                                               
        node<T>* head;                                     
        node<T>* tail;                                     
        int len;                                           
    public:                                                
        list(){                                            
            this->len = 0;                                 
            this->head = this->tail = 0;                   
        }                                                  
        ~list(){                                           
            node<T>* n = this->head;                       
            if (!n) return;                                
            node<T>* t = NULL;                             
            while (n){                                     
                t = n->next;                               
                delete n;                                  
                n = t;                                     
            }                                              
        }                                                  

        /* other stuff */

        ostream& operator<<(ostream &o, const list<T>& l) {
            node<T>* t = l.head;                           
            while (t){                                     
                strm << *(t->value);                       
                if (!t->next) break;                       
                strm << ", ";                              
                t = t->next;                               
            }                                              
            return strm;                                   
        }                                                  
};             

I get the following compile error:

rm bin *.o -f
g++ -g -Wall main.cpp -o bin
main.cpp:110: error: 'std::ostream& list<T>::operator<<(std::ostream&, const list<T>&)' must take exactly one argumentmain.cpp: In function 'int main(int, char**)':
main.cpp:151: error: no match for 'operator<<' in 'std::cout << l'
/usr/include/c++/4.4/ostream:108: note: candidates are: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>& (*)(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
... other errors
make: *** [main] Error 1

So, here's my question. What do I need to do to make this work? I was trying to follow this question as an example.

Community
  • 1
  • 1
bitcycle
  • 7,632
  • 16
  • 70
  • 121

3 Answers3

2

Your operator<< is declared as a member function. You need to make it a free function instead, i.e. define it outside the class:

template <class T>
class list {
    // ...
};

template <class T>
ostream& operator<<(ostream &o, const list<T>& l) 
{
    // ...
};

If you need to make your operator<< a friend of the class then please have a look at my answer to this question

Also, I noticed that you're using ostream without std::, implying that you're using using namespace std.

If you're doing that, then it's a really bad idea to call your class list, since there is a std::list that will be pulled into scope by using namespace std if #include <list> is added to the file at any time in the future.

Community
  • 1
  • 1
je4d
  • 7,628
  • 32
  • 46
  • Or just put `friend` in-front of the definition inside the class (no need to move it out). – Martin York Nov 20 '12 at 01:26
  • @LokiAstari true, that does work, but it's abuse of the `friend` keyword to place the `operator<<` overload in a different scope. So by [the principle of least astonishment](http://en.wikipedia.org/wiki/Principle_of_least_astonishment), I wouldn't recommend actually doing it. – je4d Nov 20 '12 at 01:36
  • @je4d: where did you learn that it's an abuse of `friend`? I've always preferred leaving the declaration as a friend inside the class. – moswald Nov 20 '12 at 02:42
1

Can you try to make the operator<< function as friend?

....;
friend ostream& operator<<(ostream &o, const list<T>& l) {
....;

This is because as shown in the other question, this function has to be declared as a free function, if declared as a member of list, it is only used if it is actually called on a list object itself.


Edit

Good catch by @je4d.

Looking at your code it looks like you dont need the operator to be a friend since im guessing you will have accessors for head and tail. It would be easier to just declare and define it outside the class as a templated free function.

Community
  • 1
  • 1
Karthik T
  • 31,456
  • 5
  • 68
  • 87
0

I ended up using a combination of boost::lexical_cast<std::string> and the suggested ostream& operator << method.

bitcycle
  • 7,632
  • 16
  • 70
  • 121