Dave Dribin has a puzzler about being able to cout << vector << endl; at his web page. As I’ve been reading about this kind of stuff recently, I have a sample explanation and also, for fun, an explanation of why it’s impossible to do this correctly after the jump…
First of all, the obvious implementation:
#include
#include
template
std::ostream& operator< <(std::ostream& out, std::vector
{
string comma("");
out < < "vector<>: {";
for(std::vector
it != vec.end(); ++it)
{
out < < comma << *it;
if (comma.empty())
comma = ", ";
}
out << "};";
return out;
}
the comma thing is just me getting cutesy, but you get the idea.
However, here's the problem with this: This is actually ::operator< <(std::ostream&, std::vectorusing
statement. Two, if any function with the same name (ignoring parameters) exists in that namespace, you do NOT need to check the global namespace.
That is std::foo(std::wstring); blocks ::foo(std::wstring). But std::foo(int i) ALSO blocks ::foo(std::string). For more information, see GotW #30.
One illegal fix: wrap it in namespace std { }
. You can NEVER put something that's not part of the C++ standard API in namespace std. (See stdext::hash_map).
One potential fix: Put it in an anonymous namespace {}
block. I need to find a language lawyer and see if that's valid and if that circumvents the namespace blocking rule above.