I'm struggling to understand what exactly happens when passing a reference-to-function to a function as a universal reference (what type is being deduced). Let's suppose we have a function foo that takes a param as a universal reference:
template<typename T>
void foo(T&& param)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
And then let's do the following:
void(&f)(int) = someFunction;
foo(f);
The result will be:
void foo(T&&) [with T = void (&)int]
This is perfectly understandable: we are passing lvalue to our function foo, so the deduced type is void(&)int, and the type of the param will be "void(&& &)int" which under reference collapsing rules becomes void(&)int. Param will be just an lvalue reference to a function.
But when I do the following:
void(&f)(int) = someFunction;
foo(std::move(f));
foo will print:
void foo(T&&) [with T = void (&)int]
which is exactly the same as before! What is happening here? Why the result is the same as when passing lvalue? I would expect that since we are passing rvalue to foo, the deduced type should be T = void(int), and param should become void(&&)int. This always happen with all other "normal" types (like classes, primitive types, etc.) Why is it different when dealing with function references?