I am trying to understand what exactly happens when a function-link is passed to a function as a universal link (which type is inferred). Suppose we have a function foo that takes a parameter as a universal reference:
template<typename T> void foo(T&& param) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
And then do the following:
void(&f)(int) = someFunction; foo(f);
The result will be:
void foo(T&&) [with T = void (&)int]
This is completely understandable: we pass an lvalue to our function foo, so the type deduced is void (&) int, and the parameter type is "void (& & & &) int", which, by reference to discard rules, becomes invalid (&) int. The parameter will only be an lvalue reference to the 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's going on here? Why is the result the same as passing lvalue? I would expect that since we pass the rvalue to foo, the type inference should be T = void (int), and param should become void (& &) int. This always happens with all other "normal" types (for example, classes, primitive types, etc.). Why is this different when working with function references?
source share