title: operator<< overload for smart pointers
body: <p>I would like to overload the operator&lt;&lt; to allow it to work with <code>shared_ptr</code>.</p>
  
  <pre><code>template&lt;typename T&gt;
  struct foo
  {
      virtual foo&amp; operator&lt;&lt;(const T&amp; e) = 0;
  };
  
  foo&lt;int&gt; f1;
  f1 &lt;&lt; 1;
  
  std::shared_ptr&lt;foo&lt;int&gt;&gt; f2(new foo&lt;int&gt;());
  f2 &lt;&lt; 1;
  </code></pre>
  
  <p>My first try is the following, but the problem is that it with also enable the behavior for any class.</p>
  
  <pre><code>template&lt;typename T, typename U&gt;
  const std::shared_ptr&lt;T&gt;&amp; operator&lt;&lt;(const std::shared_ptr&lt;T&gt;&amp; o, const U&amp; e)
  {
      *o &lt;&lt; e;
      return o;
  }
  </code></pre>
  
  <p>My second try is the following:</p>
  
  <pre><code>template&lt;typename T, typename U&gt;
  const std::shared_ptr&lt;foo&lt;T&gt;&gt;&amp; operator&lt;&lt;(const std::shared_ptr&lt;foo&lt;T&gt;&gt;&amp; o, const U&amp; e)
  {
      *o &lt;&lt; e;
      return o;
  }
  </code></pre>
  
  <p>The problem with this solution is not work for types inheriting foo since <code>T</code> cannot be automatically deduced.</p>
  
  <p>So I could skip <code>U</code> and use <code>T</code> instead, in which case T will be deduced from the second argument and the argument for <code>o</code> can be converted into <code>foo&lt;T&gt;</code>.</p>
  
  <pre><code>template&lt;typename T, typename U&gt;
  const std::shared_ptr&lt;foo&lt;T&gt;&gt;&amp; operator&lt;&lt;(const std::shared_ptr&lt;foo&lt;T&gt;&gt;&amp; o, const T&amp; e)
  {
      *o &lt;&lt; e;
      return o;
  }
  </code></pre>
  
  <p>But then the following will not work:</p>
  
  <pre><code>struct c    
  {    
  };
  
  struct a
  {
      a();
      a(c); // implicit conversion
  };
  
  struct b
  {
      operator a(); // implicit conversion
  };
  
  auto f = std::make_shared&lt;foo&lt;a&gt;&gt;();
  f &lt;&lt; c; // doesn't work.
  f &lt;&lt; b; // doesn't work.
  </code></pre>
  
  <p>Any ideas on how make a working solution?</p>