title: Using a variadic template method of a template class inside a variadic template function
body: <p>The following code will not compile in either intel or gcc. The crux of the problem appears to be that a static method variadic template of a template class called with a parameter pack expansion is considered bad syntax on the first pass of the compiler.</p>
  
  <pre><code>template&lt;typename T&gt;
  class foo
  {
  public:
      template &lt;bool do_other_thing_too, typename... ArgTypes&gt;
      static T doThing(ArgTypes... args)
      {
          std::vector&lt;T&gt; outs = { args... };
          T out = 0;
          for (auto V : outs) out += V;
          // the actual code involves templates using SFINAE, and so must either
          // be in this template's parameters or be copied, once for each value 
          // of the bool
          if (do_other_thing_too)
          {
              out *= 1.5;
          }
          return out;
      }
  };
  
  struct bar
  {
      int data = 3;
      template&lt;bool do_other_thing_too = true, typename T, typename...ArgTypes&gt;
      T&amp; doThings(T&amp; out, ArgTypes... args)
      {
          //the line of the code causing the problem
          out = foo&lt;T&gt;::doThing&lt;do_other_thing_too&gt;(data, args...);
          return out;
      }
  };
  
  int main()
  {
      bar george;
      int a = 0;
      george.doThings(a, 12, 10.4, 3.2f, 4ll, 2l);
      return 0;
  }
  </code></pre>
  
  <p>It gives the following errors in gcc:</p>
  
  <pre><code>Test.cpp:27:61: error: expected ')' before '...' token
           out = foo&lt;T&gt;::doThing&lt;do_other_thing_too&gt;(data, args...);
                                                               ^
  Test.cpp:27:65: error: parameter packs not expanded with '...':
           out = foo&lt;T&gt;::doThing&lt;do_other_thing_too&gt;(data, args...);
                                                                   ^
  Test.cpp:27:65: note:         'args'
  </code></pre>
  
  <p>I have done a decent bit of fiddling with the code, it will not happen if foo's T parameter is folded into foo::doThing's template i.e.</p>
  
  <pre><code>class foo
  {
  public:
      template &lt;typename T, bool do_other_thing_too, typename... ArgTypes&gt;
      static T doThing(ArgTypes... args)
  </code></pre>
  
  <p>Also, there is no problem with calling <code>foo&lt;int&gt;::doThing&lt;true&gt;(3, 12, 10.4, 3.2f, 4ll, 2l)</code> directly but neither option is available in the code that spawned this.
  I have a solution to the problem in the short term <code>do_other_thing_too</code> can be a template parameter in bar, passed by value to foo, and then I can if/else to shove it back into the template that actually needs it, but that is kinda ugly, and I really want to know what is actually causing the problem here.</p>
  
  <p>relevant TLDR on the one this is a 'duplicate' of:
  It is possible for template syntax to be ambiguous </p>
  
  <pre><code>foo&lt;T&gt;::doThing&lt;do_other_thing_too&gt;(data, args...);
  </code></pre>
  
  <p><em>could</em> be referencing a value <code>doThing</code> that is being checked for being less than <code>do_other_thing_too</code> But if you change it to</p>
  
  <pre><code>foo&lt;T&gt;::template doThing&lt;do_other_thing_too&gt;(data, args...);
  </code></pre>
  
  <p>it knows it is a function</p>