title: Error while trying to overload operator << for all std container printing, why?
body: <p>I am trying to build an <code>operator &lt;&lt;</code> overload to print all the standard library container types. So far, the overload works well, but when I use it in a generic program, it breaks when I try to print a simple <code>std::string</code>. In fact, this program:</p>
  <pre><code>#include &lt;iostream&gt;
  #include &lt;utility&gt;
  #include &lt;vector&gt;
  #include &lt;map&gt;
  #include &lt;string&gt;
  
  // Helper Function to Print Test Containers (Vector and Map)
  template &lt;typename T, typename U&gt;
  inline std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const std::pair&lt;T, U&gt;&amp; p) {
      out &lt;&lt; &quot;[&quot; &lt;&lt; p.first &lt;&lt; &quot;, &quot; &lt;&lt; p.second &lt;&lt; &quot;]&quot;;
      return out;
  } 
  
  template &lt;template &lt;typename, typename...&gt; class ContainerType, typename 
  ValueType, typename... Args&gt;
  std::ostream&amp; operator &lt;&lt;(std::ostream&amp; os, const ContainerType&lt;ValueType, Args...&gt;&amp; c) {
      for (const auto&amp; v : c) {
          os &lt;&lt; v &lt;&lt; ' ';
      }
    return os;
  }
  
  int main()
   {
    std::vector &lt;int&gt; v = { 1,2,3 };
    std::cout &lt;&lt; v;
  
    std::map &lt;int,int&gt; m = { { 1, 1} , { 2, 2 }, { 3, 3 } };
    std::cout &lt;&lt; m;
  
    std::string s = &quot;Test&quot;;
    std::cout &lt;&lt; s;
   }
  </code></pre>
  <p>Gives me this error:</p>
  <pre><code>prove.cpp: In function ‘int main()’:
  prove.cpp:32:13: error: ambiguous overload for ‘operator&lt;&lt;’ (operand types are ‘std::ostream’ {aka ‘std::basic_ostream&lt;char&gt;’} and ‘std::string’ {aka ‘std::__cxx11::basic_string&lt;char&gt;’})
     32 |   std::cout &lt;&lt; s;
        |   ~~~~~~~~~ ^~ ~
        |        |       |
        |        |       std::string {aka std::__cxx11::basic_string&lt;char&gt;}
        |        std::ostream {aka std::basic_ostream&lt;char&gt;}
  prove.cpp:16:15: note: candidate: ‘std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const ContainerType&lt;ValueType, Args ...&gt;&amp;) [with ContainerType = std::__cxx11::basic_string; ValueType = char; Args = {std::char_traits&lt;char&gt;, std::allocator&lt;char&gt;}; std::ostream = std::basic_ostream&lt;char&gt;]’
     16 | std::ostream&amp; operator &lt;&lt;(std::ostream&amp; os, const ContainerType&lt;ValueType, Args...&gt;&amp; c) {
        |               ^~~~~~~~
  In file included from /usr/include/c++/9/string:55,
                   from /usr/include/c++/9/bits/locale_classes.h:40,
                   from /usr/include/c++/9/bits/ios_base.h:41,
                   from /usr/include/c++/9/ios:42,
                   from /usr/include/c++/9/ostream:38,
                   from /usr/include/c++/9/iostream:39,
                   from prove.cpp:1:
  /usr/include/c++/9/bits/basic_string.h:6419:5: note: candidate: ‘std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::operator&lt;&lt;(std::basic_ostream&lt;_CharT, _Traits&gt;&amp;, const std::__cxx11::basic_string&lt;_CharT, _Traits, _Allocator&gt;&amp;) [with _CharT = char; _Traits = std::char_traits&lt;char&gt;; _Alloc = std::allocator&lt;char&gt;]’
   6419 |     operator&lt;&lt;(basic_ostream&lt;_CharT, _Traits&gt;&amp; __os,
        |     ^~~~~~~~
  </code></pre>
  <p>I think that the problem is due to the fact that this overload is used to print also simple <code>std::string</code> objects, but I didn't find any suitable way to solve this so far. Any help? thanks.</p>