title: "candidate template ignored: could not match ..." for template function argument to template function
body: <h1>overview</h1>
  
  <p>i am attempting to pass a lambda to a template function which takes a template function type. on compilation is errors with <code>candidate template ignored: could not match...</code>.</p>
  
  <p>however, when i try to pass the same lambda to a template class which takes a template function type, it compiles and works.</p>
  
  <h1>questions</h1>
  
  <ol>
  <li>why does this work for a template class but not a template function?</li>
  <li>is there a way to make this work?</li>
  <li>what is the extra expected parameter to the template function type when i try this with the template function (see below for more details)?</li>
  </ol>
  
  <h1>code</h1>
  
  <p>consider the following code (c++17)</p>
  
  <pre><code>#include &lt;functional&gt;
  
  // define the template function type
  template&lt;typename T, typename...S&gt;
  using compose_fn_t = std::function&lt;T(S...)&gt;;
  
  
  // define a template function which accepts the template function type
  template&lt;typename T, typename... S&gt;
  void compose(compose_fn_t&lt;T, S...&gt; fn) {};
  
  // define a template class which accepts the template function type
  template&lt;typename T, typename... S&gt;
  class Compose {
  public:
    Compose(compose_fn_t&lt;T, S...&gt; fn) {};
  };
  
  // some arbitrary types
  struct A{};
  struct B{};
  struct C{};
  
  int main() {
  
    compose&lt;A, B, C&gt;
      ([] (B b, C c) -&gt; A { return {}; });  // this will not compile!
  
    Compose&lt;A, B, C&gt;
      ([] (B b, C c) -&gt; A { return {}; });  // this compiles and runs correctly!
  
    return 0;
  }
  
  </code></pre>
  
  <p>when i compile using <code>compose&lt;A, B, C&gt;</code>, it throws the following error</p>
  
  <pre><code>$ g++ -std=c++17 -o main main.cpp                                                                                                  
  main.cpp:18:3: error: no matching function for call to 'compose'
    compose&lt;A, B, C&gt;
    ^~~~~~~~~~~~~~~~
  main.cpp:8:6: note: candidate template ignored: could not match 'function&lt;A (B, C, type-parameter-0-1...)&gt;' against '(lambda at main.cpp:19:6)'
  void compose(compose_fn_t&lt;T, S...&gt; fn) {
       ^
  1 error generated.
  </code></pre>
  
  <p>what is this additional <code>type-parameter-0-1</code> type that is expected by the template function type (<code>compose_fn_t</code>)?</p>