title: How to use enable if with template arguments and parameter pack?
body: <p>I was working around with c++ templates and came across this piece of code which is using SFINAE using <code>std::enable_if</code>. I am facing two issues with this code.  </p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;string&gt;
  #include &lt;iostream&gt;
  
  enum class Type : int { First = 1, Second, Third };
  
  template &lt;Type T&gt;
  struct Symbol : public std::true_type {
    using Parent = std::true_type;
    using type = Parent::value_type;
    static constexpr type value = Parent::value;
    static constexpr type GetValue() {
          if constexpr (T == Type::First) return value;
      else return !value;
    }
  };
  
  
  template &lt;bool b&gt;
  using EnableIf = typename std::enable_if&lt;b, int&gt;::type;
  
  template &lt;Type T&gt; static constexpr bool IsTradingSymbol() {
    return Symbol&lt;T&gt;::GetValue();
  }
  
  template &lt;Type T, EnableIf&lt;IsTradingSymbol&lt;T&gt;()&gt;...&gt;
  bool GetErrorForUi(Type A) {
    return true;
  }
  template &lt;Type T, EnableIf&lt;!IsTradingSymbol&lt;T&gt;()&gt;...&gt;
  bool GetErrorForUi(Type A) {
    return false;
  }
  
  int main () {
    std::cout &lt;&lt; GetErrorForUi&lt;Type::First&gt;(Type::First) &lt;&lt; std::endl;
    std::cout &lt;&lt; GetErrorForUi&lt;Type::Second&gt;(Type::Second) &lt;&lt; std::endl;
    return 0;
  }
  </code></pre>
  
  <p>1) Why parameter pack used in <code>EnableIf&lt;IsTradingSymbol&lt;T&gt;()&gt;...</code>. If I remove the <code>...</code> then the code fails in the compilation. I am unable to deduce the exact error from the trace and why this <code>...</code> is needed at all there? (compiled with GCC 7.4.0).</p>
  
  <pre><code>enableif.cpp: In function ‘int main()’:
  enableif.cpp:43:54: error: no matching function for call to ‘GetErrorForUi&lt;First&gt;(Type)’
     std::cout &lt;&lt; GetErrorForUi&lt;Type::First&gt;(Type::First) &lt;&lt; std::endl;
                                                        ^
  enableif.cpp:26:6: note: candidate: template&lt;Type T, typename std::enable_if&lt;IsTradingSymbol&lt;T&gt;(), int&gt;::type &lt;anonymous&gt; &gt; bool GetErrorForUi(Type)
   bool GetErrorForUi(Type A) {
        ^~~~~~~~~~~~~
  enableif.cpp:26:6: note:   template argument deduction/substitution failed:
  enableif.cpp:43:54: note:   couldn't deduce template parameter ‘&lt;anonymous&gt;’
     std::cout &lt;&lt; GetErrorForUi&lt;Type::First&gt;(Type::First) &lt;&lt; std::endl;
                                                        ^
  enableif.cpp:30:6: note: candidate: template&lt;Type T, typename std::enable_if&lt;(! IsTradingSymbol&lt;T&gt;()), int&gt;::type &lt;anonymous&gt; &gt; bool GetErrorForUi(Type)
   bool GetErrorForUi(Type A) {
        ^~~~~~~~~~~~~
  enableif.cpp:30:6: note:   template argument deduction/substitution failed:
  enableif.cpp:43:54: note:   couldn't deduce template parameter ‘&lt;anonymous&gt;’
     std::cout &lt;&lt; GetErrorForUi&lt;Type::First&gt;(Type::First) &lt;&lt; std::endl;
                                                        ^
  enableif.cpp:44:56: error: no matching function for call to ‘GetErrorForUi&lt;Second&gt;(Type)’
     std::cout &lt;&lt; GetErrorForUi&lt;Type::Second&gt;(Type::Second) &lt;&lt; std::endl;
                                                          ^
  enableif.cpp:26:6: note: candidate: template&lt;Type T, typename std::enable_if&lt;IsTradingSymbol&lt;T&gt;(), int&gt;::type &lt;anonymous&gt; &gt; bool GetErrorForUi(Type)
   bool GetErrorForUi(Type A) {
        ^~~~~~~~~~~~~
  enableif.cpp:26:6: note:   template argument deduction/substitution failed:
  enableif.cpp:44:56: note:   couldn't deduce template parameter ‘&lt;anonymous&gt;’
     std::cout &lt;&lt; GetErrorForUi&lt;Type::Second&gt;(Type::Second) &lt;&lt; std::endl;
                                                          ^
  enableif.cpp:30:6: note: candidate: template&lt;Type T, typename std::enable_if&lt;(! IsTradingSymbol&lt;T&gt;()), int&gt;::type &lt;anonymous&gt; &gt; bool GetErrorForUi(Type)
   bool GetErrorForUi(Type A) {
        ^~~~~~~~~~~~~
  enableif.cpp:30:6: note:   template argument deduction/substitution failed:
  enableif.cpp:44:56: note:   couldn't deduce template parameter ‘&lt;anonymous&gt;’
     std::cout &lt;&lt; GetErrorForUi&lt;Type::Second&gt;(Type::Second) &lt;&lt; std::endl;
  </code></pre>
  
  <p>2) The code is not compiling with icc X86-64 (intel compiler 19.0.1). Does the compiler not support <code>std::enable_if</code>sfinae or is it a bug with the intel compiler itself?  </p>