lundi 29 juin 2015

Passing a reference-to-function as a universal reference

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?

Aucun commentaire:

Enregistrer un commentaire