title: Baffling variadic templates exercise
body: <p>I set myself this task to help learn variadic templates. The function <code>add_and_cat()</code> should take first a pair&lt;int,string&gt;, then a variable number of ints or strings or a mixture. As it encounters these recursively, it should subtract each int from pair.first, and concatenate each string onto pair.second. The function pp just prints the pair.</p>
  <p>It seems to work in many cases, but in others I get a compile error claiming no matching function (at the bottom) ... even though there seems to be only one perfectly obvious candidate as far as I can tell :/ I've played around and tried to reason it out but ... no luck yet. What am I missing?</p>
  <p>-------------------------- Code: ----------------------------</p>
  <pre><code>#include &lt;iostream&gt;
  
  void pp(std::pair&lt;int,std::string&gt; printme) {
      std::cout &lt;&lt; printme.first &lt;&lt; &quot; : &quot; &lt;&lt; printme.second &lt;&lt; &quot;\n&quot;;
  }
  
  //base case int
  //must be int or std::string for now
  void add_and_cat(std::pair&lt;int, std::string&gt;&amp; store, int i) {
      store.first -= i;
  }
  
  //base case string
  void add_and_cat(std::pair&lt;int, std::string&gt;&amp; store, std::string s) {
      store.second += s;
  }
  
  //full case for int
  template&lt;typename ...Ts&gt;
  void add_and_cat(std::pair&lt;int, std::string&gt;&amp; store, int i, Ts... rest) {
      store.first -= i;
      add_and_cat(store, rest...);
  }
  
  //full case for string
  template&lt;typename ...Ts&gt;
  void add_and_cat(std::pair&lt;int, std::string&gt;&amp; store, std::string s, Ts... rest) {
      store.second += s;
      add_and_cat(store, rest...);
  }
  
  
  
  int main()
  {
  
      std::pair&lt;int, std::string&gt; p{0,&quot;START&quot;};
  
      //add_and_cat(p, 1, 2, 3, 4); pp(p);                    //fine
      //add_and_cat(p, 3, 4, 5, 6); pp(p);                    //fine
      //add_and_cat(p, &quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;); pp(p);            //fine
      //add_and_cat(p, &quot;D&quot;, &quot;E&quot;, &quot;F&quot;, &quot;G&quot;); pp(p);            //fine
      //add_and_cat(p, &quot;A&quot;, 1, &quot;B&quot;); pp(p);                   //fine
      //add_and_cat(p, 1, &quot;A&quot;, 1, &quot;B&quot;); pp(p);                //compile error
      //add_and_cat(p, 1, 2, &quot;A&quot;,3); pp(p);                   //compile error
      //add_and_cat(p, &quot;A&quot;, 1, 2, &quot;B&quot;); pp(p);                //fine
      //add_and_cat(p, &quot;A&quot;, 1, 2, &quot;B&quot;,&quot;C&quot;); pp(p);            //compile error
      //add_and_cat(p, 1, 2, &quot;B&quot;,&quot;C&quot;); pp(p);             //compile error
  
  
  
      return 0;
  }
  
  </code></pre>
  <p>------------------------------ Error: -----------------------------</p>
  <pre><code>/mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp: In instantiation of ‘std::pair&lt;int, std::__cxx11::basic_string&lt;char&gt; &gt; add_and_cat(std::pair&lt;int, std::__cxx11::basic_string&lt;char&gt; &gt;&amp;, int, Ts ...) [with Ts = {const char*, int, const char*}]’:
  /mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:273:45:   required from here
  /mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:250:20: error: no matching function for call to ‘add_and_cat(std::pair&lt;int, std::__cxx11::basic_string&lt;char&gt; &gt;&amp;, const char*&amp;, int&amp;, const char*&amp;)’
    250 |  return add_and_cat(store, rest...);
        |         ~~~~~~~~~~~^~~~~~~~~~~~~~~~
  /mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:233:29: note: candidate: ‘std::pair&lt;int, std::__cxx11::basic_string&lt;char&gt; &gt; add_and_cat(std::pair&lt;int, std::__cxx11::basic_string&lt;char&gt; &gt;&amp;, int)’
    233 | std::pair&lt;int, std::string&gt; add_and_cat(std::pair&lt;int, std::string&gt;&amp; store, int i) {
        |                             ^~~~~~~~~~~
  /mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:233:29: note:   candidate expects 2 arguments, 4 provided
  /mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:240:29: note: candidate: ‘std::pair&lt;int, std::__cxx11::basic_string&lt;char&gt; &gt; add_and_cat(std::pair&lt;int, std::__cxx11::basic_string&lt;char&gt; &gt;&amp;, std::string)’
    240 | std::pair&lt;int, std::string&gt; add_and_cat(std::pair&lt;int, std::string&gt;&amp; store, std::string s) {
        |                             ^~~~~~~~~~~
  /mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:240:29: note:   candidate expects 2 arguments, 4 provided
  /mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:247:29: note: candidate: ‘template&lt;class ... Ts&gt; std::pair&lt;int, std::__cxx11::basic_string&lt;char&gt; &gt; add_and_cat(std::pair&lt;int, std::__cxx11::basic_string&lt;char&gt; &gt;&amp;, int, Ts ...)’
    247 | std::pair&lt;int, std::string&gt; add_and_cat(std::pair&lt;int, std::string&gt;&amp; store, int i, Ts... rest) {
        |                             ^~~~~~~~~~~
  /mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:247:29: note:   template argument deduction/substitution failed:
  /mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:250:28: note:   cannot convert ‘rest#0’ (type ‘const char*’) to type ‘int’
    250 |  return add_and_cat(store, rest...);
        |                            ^~~~
  </code></pre>
  <p>Thanks so much for any help!</p>