title: Overload resolution failure when streaming object via implicit conversion to string
body: <p><strong>Disclaimer:</strong> I <em>know</em> that implicit conversion to string should be avoided, and that the proper approach would be an <code>op&lt;&lt;</code> overload for <code>Person</code>.</p>
  
  <hr>
  
  <p>Consider the following code:</p>
  
  <pre><code>#include &lt;string&gt;
  #include &lt;ostream&gt;
  #include &lt;iostream&gt;
  
  struct NameType {
     operator std::string() { return "wobble"; }
  };
  
  struct Person {
     NameType name;
  };
  
  int main() {
     std::cout &lt;&lt; std::string("bobble");
     std::cout &lt;&lt; "wibble";
  
     Person p;
     std::cout &lt;&lt; p.name;
  }
  </code></pre>
  
  <p>It <a href="http://www.ideone.com/6t0EA">yields the following on GCC 4.3.4</a>:</p>
  
  <pre><code>prog.cpp: In function ‘int main()’:
  prog.cpp:18: error: no match for ‘operator&lt;&lt;’ in ‘std::cout &lt;&lt; p.Person::name’
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:112: note: candidates are: std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(std::basic_ostream&lt;_CharT, _Traits&gt;&amp; (*)(std::basic_ostream&lt;_CharT, _Traits&gt;&amp;)) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:121: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(std::basic_ios&lt;_CharT, _Traits&gt;&amp; (*)(std::basic_ios&lt;_CharT, _Traits&gt;&amp;)) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:131: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(std::ios_base&amp; (*)(std::ios_base&amp;)) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:169: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(long int) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:173: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(long unsigned int) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:177: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(bool) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/ostream.tcc:97: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(short int) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:184: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(short unsigned int) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/ostream.tcc:111: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(int) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:195: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(unsigned int) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:204: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(long long int) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:208: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(long long unsigned int) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:213: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(double) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:217: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(float) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:225: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(long double) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:229: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(const void*) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  /usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/ostream.tcc:125: note:                 std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::basic_ostream&lt;_CharT, _Traits&gt;::operator&lt;&lt;(std::basic_streambuf&lt;_CharT, _Traits&gt;*) [with _CharT = char, _Traits = std::char_traits&lt;char&gt;]
  </code></pre>
  
  <p>How come the free <code>op&lt;&lt;(ostream&amp;, string const&amp;)</code> doesn't make it into the overload set? Is this due to a combination of the desired overload being a template instantiation and ... ADL?</p>