@Sven Groot: Thanks, but I think I just discovered a way to use SFINAE to detect the presence of iterators (see my edit above), so hopefully I can completely avoid mentioning any explicit container types altogether.

Bonus question: Can we SFINAE between "*iterator == pair<K,V>" and "*iterator == T"?

Edit: I see your point about the string class, but wouldn't the string's operator<< be more specialized?