title: Partial specialization of single type template parameter class template using non-type template parameter through a dependent type
body: <p><sub><em>All standard references below refers to <a href="https://timsong-cpp.github.io/cppwp/n4659/" rel="noreferrer">N4659: March 2017 post-Kona working draft/C++17 DIS</a>.</em></sub></p>
  <hr />
  <p>Consider the following snippet:</p>
  <pre><code>#include &lt;type_traits&gt;
  
  template &lt;int N&gt; struct num {};
  
  template &lt;typename&gt; struct A;
  
  // (1)
  template &lt;int N&gt; struct A&lt;num&lt;N&gt;&gt; { using type = bool; };
  
  // (2)
  template &lt;long N&gt; struct A&lt;num&lt;N&gt;&gt; { using type = char; };
  
  static_assert(!std::is_same_v&lt;long, int&gt;, &quot;&quot;);
  
  // (A)
  static_assert(std::is_same_v&lt;A&lt;num&lt;1&gt;&gt;::type, bool&gt;, &quot;&quot;);
  
  int main() {}
  </code></pre>
  <p>The <code>static_assert</code> at <strong>(A)</strong> is successful for GCC, but fails for Clang:</p>
  <blockquote>
  <pre><code>error: static_assert failed due to 
         requirement 'std::is_same_v&lt;char, bool&gt;' &quot;&quot;
  </code></pre>
  </blockquote>
  <p>Essentially, GCC picks the perfectly matching specialization <strong>(1)</strong>, whereas Clang picks the specialization <strong>(2)</strong>.</p>
  <p>Similarly, if we remove the assertions as well as specialization <strong>(1)</strong>:</p>
  <pre><code>template &lt;int N&gt; struct num {};
  
  template &lt;typename&gt; struct A;
  
  // (2)
  template &lt;long N&gt; struct A&lt;num&lt;N&gt;&gt; { using type = char; };
  
  int main() {
    A&lt;num&lt;1&gt;&gt; a{};
    (void)a;
  }
  </code></pre>
  <p>Then GCC fails to compile the program whereas Clang accepts it.</p>
  <blockquote>
  <p>GCC:</p>
  <pre><code>error: variable '`A&lt;num&lt;1&gt; &gt; a`' has initializer but incomplete type
  </code></pre>
  </blockquote>
  <p>This behaviour holds over various GCC and Clang versions, as well as various C++ language levels over these version (C++11, C++14, C++17, C++2a).</p>
  <h3>Question</h3>
  <ul>
  <li>Is the first snippet above in fact ill-formed (no diagnostic required?), or is either GCC or Clang wrong?</li>
  </ul>
  <p>My guess is that this is ill-formed, but haven't been able to apply a relevant part of <a href="https://timsong-cpp.github.io/cppwp/n4659/temp.class.spec" rel="noreferrer">[temp.class.spec]</a> to reject it. Perhaps <a href="https://timsong-cpp.github.io/cppwp/n4659/temp.class.spec#8.1" rel="noreferrer">[temp.class.spec]/8.1</a>?</p>
  <blockquote>
  <p><strong>[temp.class.spec]/8.1</strong> The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the specialization. [ <em>Example: [...] — end example</em> ]</p>
  </blockquote>