Templates, variadic function, universal references and function pointer : an explosive cocktail <p>Consider the following code and the <code>apply</code> function :</p> <pre><code>// Include #include &lt;iostream&gt; #include &lt;array&gt; #include &lt;type_traits&gt; #include &lt;sstream&gt; #include &lt;string&gt; #include &lt;cmath&gt; #include &lt;algorithm&gt; // Just a small class to illustrate my question template &lt;typename Type, unsigned int Size&gt; class Array { // Class body (forget that, this is just for the example) public: template &lt;class... Args&gt; Array(const Args&amp;... args) : _data({{args...}}) {;} inline Type&amp; operator[](unsigned int i) {return _data[i];} inline const Type&amp; operator[](unsigned int i) const {return _data[i];} inline std::string str() { std::ostringstream oss; for (unsigned int i = 0; i &lt; Size; ++i) oss&lt;&lt;((*this)[i])&lt;&lt;" "; return oss.str(); } protected: std::array&lt;Type, Size&gt; _data; // Apply declaration public: template &lt;typename Return, typename SameType, class... Args, class = typename std::enable_if&lt;std::is_same&lt;typename std::decay&lt;SameType&gt;::type, Type&gt;::value&gt;::type&gt; inline Array&lt;Return, Size&gt; apply(Return (*f)(SameType&amp;&amp;, Args&amp;&amp;...), const Array&lt;Args, Size&gt;&amp;... args) const; }; // Apply definition template &lt;typename Type, unsigned int Size&gt; template &lt;typename Return, typename SameType, class... Args, class&gt; inline Array&lt;Return, Size&gt; Array&lt;Type, Size&gt;:: apply(Return (*f)(SameType&amp;&amp;, Args&amp;&amp;...), const Array&lt;Args, Size&gt;&amp;... args) const { Array&lt;Return, Size&gt; result; for (unsigned int i = 0; i &lt; Size; ++i) { result[i] = f((*this)[i], args[i]...); } return result; } // Example int main(int argc, char *argv[]) { Array&lt;int, 3&gt; x(1, 2, 3); std::cout&lt;&lt;x.str()&lt;&lt;std::endl; std::cout&lt;&lt;x.apply(std::sin).str()&lt;&lt;std::endl; return 0; } </code></pre> <p>The compilation fails with :</p> <pre><code>universalref.cpp: In function ‘int main(int, char**)’: universalref.cpp:45:32: erreur: no matching function for call to ‘Array&lt;int, 3u&gt;::apply(&lt;unresolved overloaded function type&gt;)’ universalref.cpp:45:32: note: candidate is: universalref.cpp:24:200: note: template&lt;class Return, class SameType, class ... Args, class&gt; Array&lt;Return, Size&gt; Array::apply(Return (*)(SameType&amp;&amp;, Args&amp;&amp; ...), const Array&lt;Args, Size&gt;&amp; ...) const [with Return = Return; SameType = SameType; Args = {Args ...}; &lt;template-parameter-2-4&gt; = &lt;template-parameter-1-4&gt;; Type = int; unsigned int Size = 3u] universalref.cpp:24:200: note: template argument deduction/substitution failed: universalref.cpp:45:32: note: mismatched types ‘SameType&amp;&amp;’ and ‘long double’ universalref.cpp:45:32: note: mismatched types ‘SameType&amp;&amp;’ and ‘float’ universalref.cpp:45:32: note: mismatched types ‘SameType&amp;&amp;’ and ‘double’ universalref.cpp:45:32: note: couldn't deduce template parameter ‘Return’ </code></pre> <p>I am not very sure why it fails. In that code, I would like :</p> <ul> <li>to keep universal references to have the most generic function</li> <li>to be able to use the syntax <code>apply(std::sin)</code> </li> </ul> <p>So what do I have to change to make it compile ?</p>