title: Counting the total number of types in a nested pack
body: <p><code>NumTypes&lt;Args...&gt;::value</code> is to give the total number of types in <code>Args...</code>, including all types in a nested packs (if any), e.g. if</p>
  
  <pre><code>using T = Group&lt;int, bool, Wrap&lt;char, Pack&lt;char, long, Group&lt;char, Object, short&gt;, short&gt;, double&gt;, long&gt;;
  </code></pre>
  
  <p>then <code>NumTypes&lt;T, int, char&gt;::value</code> will be 13 (we do not count the wrapper classes themselves).  The following code works correctly, but when I replace any of the types with <code>std::string</code> I get a flurry of <code>std::allocator</code> errors that never terminates (with GCC 4.8.1).  I suspect other types will generate the same error.  Why?  And how to fix the code to avoid this weird error?</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  
  #define show(variable) std::cout &lt;&lt; #variable &lt;&lt; " = " &lt;&lt; variable &lt;&lt; std::endl;
  
  template &lt;typename T&gt;
  struct IsPack {
      static const bool value = false;
  };
  
  template &lt;template &lt;typename...&gt; class P, typename... Args&gt;
  struct IsPack&lt;P&lt;Args...&gt;&gt; {
      static const bool value = true;
  };
  
  template &lt;typename...&gt; struct NumTypes;
  
  template &lt;typename T&gt;
  struct NumTypes&lt;T&gt; {
      static const int value = 1;
  };
  
  template &lt;template &lt;typename...&gt; class P&gt;
  struct NumTypes&lt;P&lt;&gt;&gt; { static const int value = 0; };
  
  template &lt;template &lt;typename...&gt; class P, typename First, typename... Rest&gt;
  struct NumTypes&lt;P&lt;First, Rest...&gt;&gt; {
      static const int value = IsPack&lt;First&gt;::value ?
          NumTypes&lt;First&gt;::value + NumTypes&lt;P&lt;Rest...&gt;&gt;::value :
          1 + NumTypes&lt;P&lt;Rest...&gt;&gt;::value;
  };
  
  template &lt;typename First, typename... Rest&gt;
  struct NumTypes&lt;First, Rest...&gt; {
      static const int value = NumTypes&lt;First&gt;::value + NumTypes&lt;Rest...&gt;::value;
  };
  
  template &lt;typename...&gt; struct Pack;
  template &lt;typename...&gt; struct Group;
  template &lt;typename...&gt; struct Wrap;
  struct Object {};
  
  int main() {
      using A = Pack&lt;int, Object, long&gt;;
      show (NumTypes&lt;A&gt;::value)  // 3
  
      using B = Pack&lt;int, bool, Pack&lt;char, Object&gt;, long&gt;;
      show (NumTypes&lt;B&gt;::value)  // 5
  
      using C = Group&lt;int, bool, Wrap&lt;char, Pack&lt;char, long, Group&lt;char, Object, short&gt;, short&gt;, double&gt;, long&gt;;
      show (NumTypes&lt;C&gt;::value)  // 11
  
      using D = Group&lt;Pack&lt;int, Object, double&gt;, bool, Wrap&lt;char, Pack&lt;char, double, Group&lt;char, Pack&lt;char, long, short&gt;, int, Object&gt;, short&gt;, double&gt;, long&gt;;
      show (NumTypes&lt;D&gt;::value)  // 16
  
      std::cout &lt;&lt; NumTypes&lt;A, B, int, char, C, Object, D&gt;::value &lt;&lt; std::endl;  // 38
  }
  </code></pre>