title: What is the syntax for partially specialising a template based on the number of parameters a template template parameter takes?
body: <p>Consider the following code:</p>
  
  <pre><code>template&lt;typename&gt;
  struct One {};
  
  template&lt;typename, typename&gt;
  struct Two {};
  
  template&lt;template&lt;typename...&gt; class TTP, typename...&gt;
  struct SS;
  
  #ifdef    TEST_TTP
      template&lt;template&lt;typename&gt; class OneParam,
               typename... Ts&gt;
      struct SS&lt;OneParam, Ts...&gt; {};
  
      template&lt;template&lt;typename, typename&gt; class TwoParam,
               typename... Ts&gt;
      struct SS&lt;TwoParam, Ts...&gt; {};
  #else  // TEST_TTP
      template&lt;template&lt;typename&gt; class OneParam,
               typename TParam&gt;
      struct SS&lt;OneParam, TParam&gt; {};
  
      template&lt;template&lt;typename, typename&gt; class TwoParam,
               typename TParam1,
               typename TParam2&gt;
      struct SS&lt;TwoParam, TParam1, TParam2&gt; {};
  #endif // TEST_TTP
  
  int main() {
      SS&lt;One, int&gt;       ssoi;
      SS&lt;Two, int, int&gt; sstii;
  }
  </code></pre>
  
  <p>This code will compile properly on Clang, GCC, and MSVC, if <code>TEST_TTP</code> isn't defined.  However, if it <em>is</em> defined...</p>
  
  <ul>
  <li>The code compiles properly on GCC, indicating that it recognises that <code>OneParam</code> and <code>TwoParam</code> are distinct from <code>TTP</code> in the primary template.</li>
  <li>Clang fails to recognise that <code>OneParam</code> specialises <code>TTP</code>, causing it to emit two errors (the first being that the partial specialisation doesn't specialise any template parameters, and the second being that <code>OneParam</code> conflicts with the previously-declared template template parameter).  It then emits similar errors for <code>TwoParam</code> (the first is identical, while the second says that the template template parameter has too many parameters), and an error for each instantiation of <code>SS</code> (because it considers the template to be undefined), for a total of 6 errors.</li>
  <li>MSVC emits similar errors to Clang, but more concisely: It emits C3855 (<code>OneParam</code> is incompatible with the primary template), and a C2079 (variable uses undefined type) for each instantiation of <code>SS</code>, for a total of 3 errors.</li>
  </ul>
  
  <p>Demonstrated live <a href="http://coliru.stacked-crooked.com/a/f145f13504935246" rel="noreferrer">on Coliru</a>.</p>
  
  <hr>
  
  <p>From my testing:</p>
  
  <p><strong>GCC allows a template with a template template parameter which takes a variadic parameter pack to be partially specialised based solely on the number of parameters that template template parameter takes. Clang and MSVC do not.</strong></p>
  
  <pre><code>template&lt;template&lt;typename...&gt;        class T&gt; struct S;
  template&lt;template&lt;typename&gt;           class T&gt; struct S&lt;T&gt; {}; // Only works with GCC.
  template&lt;template&lt;typename, typename&gt; class T&gt; struct S&lt;T&gt; {}; // Only works with GCC.
  </code></pre>
  
  <p><strong>Clang and MSVC are fine with this if other parameters are also specialised, however.</strong></p>
  
  <pre><code>template&lt;template&lt;typename...&gt; class T, typename... Ts&gt; struct S;
  
  template&lt;template&lt;typename&gt; class T,
           typename TParam&gt;
  struct S&lt;T, TParam&gt; {};
  
  template&lt;template&lt;typename, typename&gt; class T,
           typename TParam1,
           typename TParam2&gt;
  struct S&lt;T, TParam1, TParam2&gt; {};
  </code></pre>
  
  <p>It would thus appear that either the former isn't legal C++, or it isn't properly supported by Clang and MSVC.  So, the question is this:</p>
  
  <p><strong>Considering this, what is the proper, legal syntax for partially specialising a template, which contains a template template parameter, based on the number of parameters that template template parameter takes? If there is no legal syntax for this, is supporting it a GCC extension and/or bug?</strong></p>
  
  <p><sup>If a full record of the tests I performed, along with the original example which prompted this question, are desired, please see the edit history.</sup></p>