Let's consider the following example:
void f(int&& i)
{ }
template <typename ... X, typename ... Y>
void g(void(*p)(X&&..., Y&...))
{ }
int main()
{
g(f);
return 0;
}
Compilation fails with error
<source>:10:7: error: invalid conversion from 'void (*)(int&&)' to 'void (*)(int&)' [-fpermissive]
10 | g(f);
| ^
| |
| void (*)(int&&)
<source>:5:14: note: initializing argument 1 of 'void g(void (*)(X&& ..., Y& ...)) [with X = {}; Y = {int}]'
5 | void g(void(*p)(X&&..., Y&...))
| ~~~~~~^~~~~~~~~~~~~~~~~
Demo on godbolt.
Apparently on deducing the template arguments all the function arguments produce ordinary l-value references while the set of r-value references remains empty (contrasting my own expectations) – but why?
Side note: The problem that originally led to this question is solved by other means (recursive variadic template function producing a tuple) in the meanwhile, thus no XY-problem; asking out of curiosity – still would appreciate any other elegant solution which does not involve introducing tuples to the functions in question (f in above example).