+1 to Bazzy, I just was about to post exactly the same modified code.
I don't see why you're limiting yourself to fstream, ostream is much more general.
You are right! I had such a hard time because I wanted the body of the function outside of the class declaration. Now it looks far more civilized!
Thanks, and cheers!
I dont like your second solution. Does it not imply that operator << <int> will be a friend of my List<double> ? I think yes (although I am not sure).
At any rate, if my above concern is correct, it is a (-1) to the second solution (but still a +2 to your first one - I already changed the code this way).
[Edit:] @Athar: yes for the ostream. I can always change the fstream to ostream in 1 minute, so I will reserve that move for later - I prefer not to open up functionality I don't use. Just in case...
For example, using the const keyword artificially bans functionality that comes at no additional cost - such as modifying const objects (even if they live on the stack or are statically residing in the memory).
Ok, this is a far stretch of analogy on my part for the sake of arguing and shooting the breeze - but so is talking about "right" and "wrong" approach, especially in C++.
const correctness should be followed for a reason, so that's indeed not a good analogy.
The chance that you'll use operator<< on the "wrong" type of stream object when you actually don't mean to is essentially zero.