I haven't been able to practice programming for a few months now and have lost my ability (whatever little I had) to understand templated code. I'm trying to write a general purpose operator overload that works for C++ containers (for example, an overload to output its contents). This is what I have right now:

Code:
template <template <typename...> typename Container, typename T, typename... A>
ostream& operator << (ostream& os, const Container <T, A...>& c) {
    os << __PRETTY_FUNCTION__ << '\n';
    for (const auto& i : c) {
        os << i << ' ';
    }
    return os;
}
However, this only kinda works if I use:

Code:
    std::vector <int> v {1, 2, 3, 4};
    std::cout << v << '\n';
I'd like this to also work for std::map, let's say. But trying to do so throws me a bunch of errors (as I'd expected). std::ostream doesn't yet have an overload for std::pair, which is what gets used when using iterators on map, and so I need to define what it should do with pair.

Code:
    std::map <int, std::string> m {{1, "abcde"}, {2, "abcd"}, {3, "acde"}, {4, "ade"}};
    std::cout << m << '\n';
In hopes of getting rid of the error, I define something like this:

Code:
template <typename A, typename B> std::ostream& operator << (std::ostream& os, const std::pair <A, B>& p) {
    return os << '(' << p.first << ", " << p.second << ')';
}
This leads to ambiguity errors, which I understand why it happens but don't know how to fix. Any help regarding "Writing a general purpose overload for STL containers" will be appreciated. Thank you.