title: Exact rules for matching variadic template template parameters in partial template specialization
body: <p>While creating <a href="https://stackoverflow.com/a/72911415/17862371">this</a> answer for another question I came around the following issue. Consider this program (<a href="https://godbolt.org/z/n6YofTzGr" rel="noreferrer">godbolt</a>):</p>
  <pre><code>#include &lt;variant&gt;
  #include &lt;iostream&gt;
  
  template &lt;typename T&gt;
  struct TypeChecker {
      void operator()() {
          std::cout &lt;&lt; &quot;I am other type\n&quot;;
      }
  };
  
  template&lt;typename... Ts, template&lt;typename...&gt; typename V&gt;
  requires std::same_as&lt;V&lt;Ts...&gt;, std::variant&lt;Ts...&gt;&gt;
  struct TypeChecker&lt;V&lt;Ts...&gt;&gt;
  {
      void operator()()
      {
          std::cout &lt;&lt; &quot;I am std::variant\n&quot;;
      }
  };
  
  int main()
  {
      TypeChecker&lt;std::variant&lt;int, float&gt;&gt;{}();
      TypeChecker&lt;int&gt;{}();
  }
  </code></pre>
  <p>The output (which is also expected) is the following (with clang 14.0.0 as well as with gcc 12.1):</p>
  <pre><code>I am std::variant
  I am other type
  </code></pre>
  <p>If however the three dots in the parameter list of the template template are removed, like this (whole program live on <a href="https://godbolt.org/z/5fTannrza" rel="noreferrer">godbolt</a>):</p>
  <pre><code>template&lt;typename... Ts, template&lt;typename&gt; typename V&gt;
  </code></pre>
  <p>,then the output is different for clang and gcc. The clang 14.0.0 compiled program outputs</p>
  <pre><code>I am other type
  I am other type
  </code></pre>
  <p>whereas the gcc 12.1 compiled program outputs</p>
  <pre><code>I am std::variant
  I am other type
  </code></pre>
  <p>It seems that using the non-variadic template template exhibits different matching rules in clang and gcc. So my question is, which behavior is correct if it is even well defined, and why?</p>