There's the lazy solution:

std::vector<int> v;
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(cout, ", "));

But that has the problem of printing an extra comma at the end.

More generically, you can do:

template<typename T>
ostream& write_container(ostream &s, const T &container)
{
    bool first = true;
    cout << "{ ";
    for( typename T::const_iterator it = container.begin(); it != container.end(); ++it )
    {
        if( first )
            first = false;
        else
            cout << ", ";
        cout << *it;
    }
    cout << " }";
    return s;
}

However, you cannot overload operator<< to do this. Since containers have no common base class, the only way to do this is using templates, and the above template declaration matches basically any type. Doing the above with operator<< would make operator<< ambiguous for any type with its own operator<<, and produce some seriously weird errors.

If you insist on overloading operator<<, I think the solution using boost::enable_if giving on SO is just about the best you can do.