title: Why can't gcc deduce templated size for array argument? (C++11)
body: <p><strong>The following code gives a compiler error (gcc-4.7 run with <code>-std=c++11</code>):</strong></p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;array&gt;
  
  template &lt;typename T, int N&gt;
  std::ostream &amp; operator &lt;&lt;(std::ostream &amp; os, const std::array&lt;T, N&gt; &amp; arr) {
    int i;
    for (i=0; i&lt;N-1; ++i)
      os &lt;&lt; arr[i] &lt;&lt; " ";
    os &lt;&lt; arr[i];
    return os;
  }
  
  int main() {
    std::array&lt;double, 2&gt; lower{1.0, 1.0};
    std::cout &lt;&lt; lower &lt;&lt; std::endl;
    return 0;
  }
  </code></pre>
  
  <p><strong>Error message:</strong></p>
  
  <blockquote>
    <p>tmp6.cpp: In function ‘int main()’: tmp6.cpp:16:16: error: cannot bind<br>
    ‘std::ostream {aka std::basic_ostream}’ lvalue to<br>
    ‘std::basic_ostream&amp;&amp;’ In file included from<br>
    /usr/include/c++/4.7/iostream:40:0,<br>
                     from tmp6.cpp:1: /usr/include/c++/4.7/ostream:600:5: error:
      initializing argument 1 of ‘std::basic_ostream&lt;_CharT,<br>
    _Traits>&amp; std::operator&lt;&lt;(std::basic_ostream&lt;_CharT, _Traits>&amp;&amp;, const _Tp&amp;) [with _CharT = char; _Traits = std::char_traits; _Tp = std::array]’<br></p>
  </blockquote>
  
  <p>When I get rid of the template function declaration and replace <code>T</code> with <code>double</code> and <code>N</code> with <code>2</code>, it compiles just fine (<strong>edit: leaving <code>T</code> and replacing <code>N</code> with 2 works, but specifying <code>N=2</code> as the default argument for <code>N</code> doesn't work.</strong>). </p>
  
  <ol>
  <li>Does anyone know why gcc can't automatically bind this?</li>
  <li><del>What would be the syntax for calling the <code>&lt;&lt;</code> operator with explicitly specified template parameters?</del></li>
  </ol>
  
  <p><strong>Answer to question 2:</strong> <code>operator&lt;&lt;&lt;double, 2&gt;(std::cout, lower);</code></p>
  
  <p><strong>Edit:</strong> This is also true for the following function, which is only templated in the array size:</p>
  
  <pre><code>template &lt;int N&gt;
  void print(const std::array&lt;double, N&gt; &amp; arr) {
    std::cout &lt;&lt; "print array here" &lt;&lt; std::endl;
  }
  
  int main() {
    std::array&lt;double, 2&gt; lower{1.0, 1.0};
    print&lt;2&gt;(lower); // this works
    print(lower);    // this does NOT work
    return 0;
  }
  </code></pre>
  
  <p>Thanks a lot for your help.</p>