title: c++ functions as template arguments
body: <p>I'm experiencing some problems which can be resumed by the following piece of code:</p>
  
  <pre><code>template &lt;typename Key, typename Data, typename fct&gt;
  size_t wrapper(const std::pair&lt;Key, Data&gt; &amp; p)
  {
    return fct(p.first);
  }
  
  int main(int argc, char *argv[])
  {
    size_t val = 
      wrapper&lt;int, int, dft_hash_fct&lt;int&gt;&gt;(std::pair&lt;int,int&gt;(5,9));
  
    return 0;
  }
  </code></pre>
  
  <p>I'm using clang compiler version 3.4 and this code does not compile with the following error</p>
  
  <pre><code>test-tmp.C:17:5: error: no matching function for call to 'wrapper'
      wrapper&lt;int, int, dft_hash_fct&lt;int&gt;&gt;(std::pair&lt;int,int&gt;(5,9));
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  test-tmp.C:9:8: note: candidate template ignored: invalid explicitly-specified argument
        for template parameter 'fct'
  </code></pre>
  
  <p>The idea is to wrap a hash function (the template parameter <code>fct</code>) on <code>std::pair</code> for only taking the first field. </p>
  
  <p><code>dft_hash_fct</code> is another template defines as follows:</p>
  
  <pre><code>template &lt;typename Key&gt;
  size_t dft_hash_fct(const Key &amp; key)
  {
    return SuperFastHash(key);
  }
  </code></pre>
  
  <p>This generic function works; it has been used in other contexts.</p>
  
  <p>The purpose of all this is to reuse a hash based set (not map) as a map of keys to items of any type. The hash based ser receives a hash function in construction time.</p>
  
  <p>Thanks for your comments (David, Andrey and Kazark)</p>
  
  <p>Edited:</p>
  
  <p>Well, I see, typename fct is a type, so I cannot handle as a pointer function; sorry for the trivia. Unfortunately, I believe that the approach of passing the function as parameter in the wrapper does not work, because the hash set expects a function pointer with the following signature:</p>
  
  <pre><code>size_t (*the_function)(const Key &amp; key);
  </code></pre>
  
  <p>So, realizing this, thanks to your observations, I changed the code in question to:</p>
  
  <pre><code>template &lt;typename Key, typename Data, size_t (*fct)(const Key &amp; k)&gt;
  size_t wrapper(const std::pair&lt;Key, Data&gt; &amp; p)
  {
    return (*fct)(p.first);
  }
  
  int main(int argc, char *argv[])
  {
    size_t val = 
      wrapper&lt;int, int, dft_hash_fct&lt;int&gt;&gt;(std::pair&lt;int,int&gt;(5,9));
  
    return 0;
  }
  </code></pre>
  
  <p>that compiles, links and runs. In addition, I put this line:</p>
  
  <pre><code>size_t (*fct)(const std::pair&lt;int, int&gt;&amp;) = 
      wrapper&lt;int, int, dft_hash_fct&lt;int&gt;&gt;;
  
  cout &lt;&lt;  (*fct)(std::pair&lt;int, int&gt;(4,6)) &lt;&lt; endl;
  </code></pre>
  
  <p>And that compiles, links ans runs too. So, I can say that the compiler (and of course according to the language) can instantiate the function and handle a function pointer to it.</p>
  
  <p>So, after that I tried to modify my original code, which is a derived class of HAshSet intended for managing pairs hashed by first field.</p>
  
  <p>I declare some as:</p>
  
  <pre><code>template &lt;typename Key, typename Data&gt;
  class HashMap : public HashSet&lt;std::pair&lt;Key, Data&gt;&gt;
  {
    ...
    HashMap(size_t (*function)(const Key &amp; key))
      : HashSet&lt;Key, Data&gt;(wrapper&lt;Key, Data, function&gt;)
    {
  
    }
  
  ..
  };
  </code></pre>
  
  <p>But the compilation (with std=c++11) fails with the error</p>
  
  <pre><code>./tpl_dynSetHash.H:353:7: error: no matching constructor for initialization of
        'HashSet&lt;std::pair&lt;unsigned long, long&gt;&gt;'
      : HashSet&lt;std::pair&lt;Key,Data&gt;(
        ^
  testDynSetHash.C:178:8: note: in instantiation of member function
        'HashMap&lt;unsigned long, long&gt;::HashMap' requested here
    HMap table; 
  </code></pre>
  
  <p>However, if I substitute the call to base constructor by</p>
  
  <pre><code>: HashSet&lt;Key, Data&gt;(wrapper&lt;Key, Data, dft_hash_fct&lt;Key&gt;)
  </code></pre>
  
  <p>That compiles fine. Thus, I believe that the problem is with the parameter type declaration (but I do not know what is). </p>