title: "ambiguous overload for 'operator<<'" *without* a catch-all overload
body: <p>So I am trying to implement the <a href="http://xorshift.di.unimi.it/" rel="nofollow">xorshift</a> PRNGs as a parameterised STL-style class from <code>random</code>, like e.g. <code>std::mersenne_twister_engine</code>, so I can use it with those quite convenient distributions from the <code>random</code> library etc.</p>
  
  <p>Anyway, I have a problem overloading the <code>operator&lt;&lt;</code> and, frankly, I am <em>completely</em> stumped.</p>
  
  <p>The class is parameterised like this:</p>
  
  <pre><code>template &lt;size_t __n,
            int_least8_t __a, int_least8_t __b, int_least8_t __c,
            uint64_t __m&gt;
  class xorshift_engine
  {
  ...
  </code></pre>
  
  <p>The overload is declared as a <code>friend</code> inside the class like this:</p>
  
  <pre><code>template &lt;size_t __n_,
            int_least8_t __a_, int_least8_t __b_, int_least8_t __c_,
            uint64_t __m_,
            typename _CharT, typename _Traits&gt;
  friend std::basic_istream&lt;_CharT, _Traits&gt;&amp;
  operator&lt;&lt; (std::basic_ostream&lt;_CharT, _Traits&gt;&amp; _os,
              const xorshift_engine&lt;__n_, __a_, __b_, __c_, __m_&gt;&amp; _x);
  </code></pre>
  
  <p>and its implementation outside the class looks like this:</p>
  
  <pre><code>template &lt;size_t __n,
            int_least8_t __a, int_least8_t __b, int_least8_t __c,
            uint64_t __m,
            typename _CharT, typename _Traits&gt;
  std::basic_ostream&lt;_CharT, _Traits&gt;&amp;
  operator&lt;&lt; (std::basic_ostream&lt;_CharT, _Traits&gt;&amp; _os,
              const xorshift_engine&lt;__n, __a, __b, __c, __m&gt;&amp; _x)
  {
      ...
  }
  </code></pre>
  
  <p>When I try to compile the following:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;random&gt;
  #include "xorshift.hpp"
  
  using namespace std;
  
  int main()
  {
      xorshift1024star bip(2345);
      mt19937_64 bip2(2345);
      cout &lt;&lt; bip &lt;&lt; endl;
      cout &lt;&lt; endl &lt;&lt; bip2 &lt;&lt; endl;
      return 0;
  }
  </code></pre>
  
  <p>(<code>xorshift1024star</code> is just an instantiation of the <code>xorshift_engine</code> class:</p>
  
  <pre><code>typedef xorshift_engine&lt;16, -31, 11, 30, 1181783497276652981ULL&gt; xorshift1024star;
  </code></pre>
  
  <p>) I get this error (I replaced my username in the file paths with <code>---</code>):</p>
  
  <pre><code>C:\Users\---\Documents\randgen.cpp: In function 'int main()':
  C:\Users\---\Documents\randgen.cpp:11:7: error: ambiguous overload for 'operator&lt;&lt;' (operand types are 'std::ostream {aka std::basic_ostream&lt;char&gt;}' and 'xorshift1024star {aka xorshift_engine&lt;16ull, -31, 11, 30, 1181783497276652981ull&gt;}')
    cout &lt;&lt; bip &lt;&lt; endl;
         ^
  C:\Users\---\Documents\randgen.cpp:11:7: note: candidates are:
  In file included from C:\Users\---\Documents\randgen.cpp:3:0:
  C:\Users\---\Documents\xorshift.hpp:898:1: note: std::basic_ostream&lt;_CharT, _Traits&gt;&amp; operator&lt;&lt;(std::basic_ostream&lt;_CharT, _Traits&gt;&amp;, const xorshift_engine&lt;__n, __a, __b, __c, __m&gt;&amp;) [with long long unsigned int __n = 16ull; signed char __a = -31; signed char __b = 11; signed char __c = 30; long long unsigned int __m = 1181783497276652981ull; _CharT = char; _Traits = std::char_traits&lt;char&gt;]
   operator&lt;&lt; (std::basic_ostream&lt;_CharT, _Traits&gt;&amp; _os,
   ^
  C:\Users\---\Documents\xorshift.hpp:858:2: note: std::basic_istream&lt;_CharT, _Traits&gt;&amp; operator&lt;&lt;(std::basic_ostream&lt;_CharT, _Traits&gt;&amp;, const xorshift_engine&lt;__n_, __a_, __b_, __c_, __m_&gt;&amp;) [with long long unsigned int __n_ = 16ull; signed char __a_ = -31; signed char __b_ = 11; signed char __c_ = 30; long long unsigned int __m_ = 1181783497276652981ull; _CharT = char; _Traits = std::char_traits&lt;char&gt;; long long unsigned int __n = 16ull; signed char __a = -31; signed char __b = 11; signed char __c = 30; long long unsigned int __m = 1181783497276652981ull]
    operator&lt;&lt; (std::basic_ostream&lt;_CharT, _Traits&gt;&amp; os,
    ^
  In file included from C:/mingw-w64/x86_64-4.9.0-posix-seh-rt_v3-rev1/mingw64/x86_64-w64-mingw32/include/c++/iostream:39:0,
                   from C:\Users\---\Documents\randgen.cpp:1:
  C:/mingw-w64/x86_64-4.9.0-posix-seh-rt_v3-rev1/mingw64/x86_64-w64-mingw32/include/c++/ostream:602:5: note: std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::operator&lt;&lt;(std::basic_ostream&lt;_CharT, _Traits&gt;&amp;&amp;, const _Tp&amp;) [with _CharT = char; _Traits = std::char_traits&lt;char&gt;; _Tp = xorshift_engine&lt;16ull, -31, 11, 30, 1181783497276652981ull&gt;] &lt;near match&gt;
       operator&lt;&lt;(basic_ostream&lt;_CharT, _Traits&gt;&amp;&amp; __os, const _Tp&amp; __x)
       ^
  C:/mingw-w64/x86_64-4.9.0-posix-seh-rt_v3-rev1/mingw64/x86_64-w64-mingw32/include/c++/ostream:602:5: note:   no known conversion for argument 1 from 'std::ostream {aka std::basic_ostream&lt;char&gt;}' to 'std::basic_ostream&lt;char&gt;&amp;&amp;'
  </code></pre>
  
  <p>For reference, this is how the overload is declared inside <code>mersenne_twister_engine</code> in <code>bits/random.h</code>:</p>
  
  <pre><code>template&lt;typename _UIntType1,
           size_t __w1, size_t __n1,
           size_t __m1, size_t __r1,
           _UIntType1 __a1, size_t __u1,
           _UIntType1 __d1, size_t __s1,
           _UIntType1 __b1, size_t __t1,
           _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
           typename _CharT, typename _Traits&gt;
  friend std::basic_ostream&lt;_CharT, _Traits&gt;&amp;
  operator&lt;&lt;(std::basic_ostream&lt;_CharT, _Traits&gt;&amp; __os,
             const std::mersenne_twister_engine&lt;_UIntType1, __w1, __n1,
             __m1, __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
             __l1, __f1&gt;&amp; __x);
  </code></pre>
  
  <p>and its implementation in <code>bits/random.tcc</code>:</p>
  
  <pre><code>template&lt;typename _UIntType, size_t __w,
           size_t __n, size_t __m, size_t __r,
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
           _UIntType __f, typename _CharT, typename _Traits&gt;
  std::basic_ostream&lt;_CharT, _Traits&gt;&amp;
  operator&lt;&lt;(std::basic_ostream&lt;_CharT, _Traits&gt;&amp; __os,
             const mersenne_twister_engine&lt;_UIntType, __w, __n, __m,
             __r, __a, __u, __d, __s, __b, __t, __c, __l, __f&gt;&amp; __x)
  {
    ...
  }
  </code></pre>
  
  <p>If I comment out the <code>cout &lt;&lt; bip &lt;&lt; endl;</code> line in my test code, it compiles and runs without error, so this overload is fine, but mine is not.</p>
  
  <p>I am completely out of ideas. What am I missing? I would be more than grateful if someone could help me.</p>
  
  <hr>
  
  <p><strong>edit:</strong> For those suggesting it's the "template friends" problem which I should solve by forward-declaring the function, I have just added</p>
  
  <pre><code>template &lt;size_t __n,
            int_least8_t __a, int_least8_t __b, int_least8_t __c,
            uint64_t __m&gt;
  class xorshift_engine;
  
  template &lt;size_t __n,
            int_least8_t __a, int_least8_t __b, int_least8_t __c,
            uint64_t __m,
            typename _CharT, typename _Traits&gt;
  std::basic_ostream&lt;_CharT, _Traits&gt;&amp;
  operator&lt;&lt; (std::basic_ostream&lt;_CharT, _Traits&gt;&amp; _os,
              const xorshift_engine&lt;__n, __a, __b, __c, __m&gt;&amp; _x);
  </code></pre>
  
  <p>before the class body/implementation, and I get the same error upon attempting to compile.</p>
  
  <hr>
  
  <p><strong>edit2:</strong> Simplified example giving the same compile error:</p>
  
  <pre><code>//file "failclass.hpp"
  
  #ifndef _FAILCLASS_HPP
  #define _FAILCLASS_HPP
  
  #include &lt;iosfwd&gt;
  #include &lt;type_traits&gt;
  
  template &lt;int n&gt;
  class failclass
  {
  private:
      static constexpr int k = n;
  
  public:
      template&lt;int n1, typename _CharT, typename _Traits&gt;
      friend std::basic_istream&lt;_CharT, _Traits&gt;&amp;
      operator&lt;&lt; (std::basic_ostream&lt;_CharT, _Traits&gt;&amp; _os,
                  const failclass&lt;n1&gt;&amp; _x);
  };
  
  template&lt;int n1, typename _CharT, typename _Traits&gt;
  std::basic_ostream&lt;_CharT, _Traits&gt;&amp;
  operator&lt;&lt; (std::basic_ostream&lt;_CharT, _Traits&gt;&amp; _os,
              const failclass&lt;n1&gt;&amp; _x)
  {
      _os &lt;&lt; _x.k;
      return _os;
  }
  
  #endif // _FAILCLASS_HPP
  </code></pre>
  
  <p>Try to compile this:</p>
  
  <pre><code>//file "failtest.cpp"
  
  #include &lt;iostream&gt;
  #include "failclass.hpp"
  
  using namespace std;
  
  int main()
  {
      failclass&lt;5&gt; a;
      cout &lt;&lt; a;
      return 0;
  }
  </code></pre>