Originally Posted by
CornedBee
Actually, the way templates work, it's only a requirement if you actually call display(). You can store objects in the list that do not overload << as long as you don't call display() for that particular list.
Ah, that I didn't know, thinking that all methods need to be compilable if a templated class is instantiated.
If possible, what do you recommend me to change? The private variable of *first to public? I understand that would ruin the concept of data hiding because I'm quite raw in the operator overloading.
Normally, displaying the contents is not the kind of task you'd expect from a List. A list's main task is to hold data.
The list should provide some means to iterate over its contents, so the user can access the contents of each node and deside what to do with it.
Supposing the following class:
Code:
class MyNumber
{
public:
MyNumber(int n): value(n) {}
void print() const {std::cout << value << '\n';}
private:
int value;
};
If you stored those in a std::list, that would give you iterators that you can use to access each MyNumber in the list and call the print method.
Code:
//create a std::list with some data
std::list<MyNumber> myList;
for (int i = 0; i < 10; ++i) {
myList.push_back(i);
}
//Now iterate over the list and print each number
for (std::list<MyNumber>::iterator it = myList.begin(); it != myList.end(); ++it) {
it->print();
}
Note, that the iterator does not expose the list itself (for example a head pointer). It only lets you move through the list (from begin() to end()) and access each MyNumber that you have stored in it.
Writing your own iterators is a bit of a black magic (there's a recent thread discussing that), so you might stay with your display() method and overload the stream << operator for MyNumber. This is done like that:
Code:
class MyNumber
{
public:
MyNumber(int n): value(n) {}
friend std::ostream& operator<< (std::ostream& os, const MyNumber& num);
private:
int value;
};
std::ostream& operator<< (std::ostream& os, const MyNumber& num)
{
return os << num.value;
}
The overload is a free function which is declared to be a friend of MyNumber, so it can access the otherwise private value member. Now MyNumber is "coutable":
Code:
MyNumber a(12), b(32);
std::cout << "First: " << a << ", second: " << b << std::endl;