title: bar(type (&)[x]) definition does not match bar(type (&)[x]) declaration?
body: <p>This is a follow up of <a href="https://stackoverflow.com/q/64598755/4117728">Template class type alias failing substitution in member declaration</a></p>
  <p>Consider this code:</p>
  <pre><code>// A
  template &lt;typename T&gt;
  struct foo {
      using type = unsigned;
     
      template &lt;type x&gt;
      void bar(type (&amp;)[x]);
  };
      
  template &lt;typename T&gt;
  template &lt;typename foo&lt;T&gt;::type x&gt;
  void foo&lt;T&gt;::bar(type (&amp;)[x]){}
  </code></pre>
  <p><a href="https://godbolt.org/z/vvEfnx" rel="noreferrer">gcc emits the following error:</a></p>
  <pre><code>&lt;source&gt;:13:6: error: no declaration matches 'void foo&lt;T&gt;::bar(foo&lt;T&gt;::type (&amp;)[x])'
     13 | void foo&lt;T&gt;::bar(type (&amp;)[x]){}
        |      ^~~~~~
  &lt;source&gt;:8:10: note: candidate is: 'template&lt;class T&gt; template&lt;unsigned int x&gt; void foo&lt;T&gt;::bar(foo&lt;T&gt;::type (&amp;)[x])'
      8 |     void bar(type (&amp;)[x]);
        |          ^~~
  &lt;source&gt;:4:8: note: 'struct foo&lt;T&gt;' defined here
      4 | struct foo {
        |        ^~~
  Compiler returned: 1
  </code></pre>
  <p><a href="https://godbolt.org/z/Kx6s5q" rel="noreferrer">clang</a>:</p>
  <pre><code>&lt;source&gt;:13:14: error: out-of-line definition of 'bar' does not match any declaration in 'foo&lt;T&gt;'
  void foo&lt;T&gt;::bar(type (&amp;)[x]){}
               ^~~
  1 error generated.
  Compiler returned: 1
  </code></pre>
  <p>When I remove what is identical in the erroneous definition and the candidate I get this:</p>
  <pre><code>// B
  template &lt;typename T&gt;
  struct foo {
      using type = unsigned;
  
      template &lt;type x&gt;
      void bar();
  };
  
  template &lt;typename T&gt;
  template &lt;typename foo&lt;T&gt;::type x&gt;
  void foo&lt;T&gt;::bar(){}
  </code></pre>
  <p>This compiles fine (<a href="https://godbolt.org/z/1beTqW" rel="noreferrer">gcc</a> / <a href="https://godbolt.org/z/Yo9qoz" rel="noreferrer">clang</a>)</p>
  <p>An attempt to answer the original question (by Darhuuk, slightly modified) was this:</p>
  <pre><code>// C
  #include &lt;type_traits&gt;
  
  template &lt;typename T&gt; struct length { using type = unsigned int; };    
  template &lt;typename T&gt; using length_t = typename length&lt;T&gt;::type;
  
  template &lt;typename type&gt;
  class Object {
    template &lt;length_t&lt;Object&lt;type&gt;&gt; length&gt;
    void put(type (&amp;)[length]);
  };
  
  template &lt;typename type&gt;
  template &lt;length_t&lt;Object&lt;type&gt;&gt; length&gt;
  void Object&lt;type&gt;::put(type (&amp;)[length]) {}
  
  int main() {}
  </code></pre>
  <p>Clang seems to have similar problems as with the original code and <a href="https://godbolt.org/z/Wj5Yr6" rel="noreferrer">emits the error</a>:</p>
  <pre><code>&lt;source&gt;:15:20: error: out-of-line definition of 'put' does not match any declaration in 'Object&lt;type&gt;'
  void Object&lt;type&gt;::put(type (&amp;)[length]) {}
                     ^~~
  1 error generated.
  </code></pre>
  <p>while <a href="https://godbolt.org/z/9MGd7j" rel="noreferrer">gcc compiles it without complaints</a>.</p>
  <p>Who is right about <code>C</code>? Is it a bug in clang or is gcc being lax?</p>
  <p>Why does <code>A</code> not compile while <code>B</code> does?</p>