Übergeben einer Referenz auf eine Funktion als universelle Referenz

Ich habe Probleme zu verstehen, was genau passiert, wenn eine Referenz auf eine Funktion als universelle Referenz übergeben wird (welcher Typ wird abgeleitet?). Nehmen wir an, wir haben eine Funktion foo, die einen Parameter als universelle Referenz verwendet:

template<typename T>
void foo(T&& param)
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

Und dann machen wir folgendes:

void(&f)(int) = someFunction;
foo(f);

Das Ergebnis wird sein:

void foo(T&&) [with T = void (&)int]

Das ist vollkommen verständlich: Wir übergeben lvalue an unsere Funktion foo, daher ist der abgeleitete Typ void (&) int, und der Typ des Parameters ist "void (&& &) int", was unter Verweis auf Kollapsregeln ungültig wird ( &) int. Param ist nur eine lWert-Referenz auf eine Funktion.

Aber wenn ich das Folgende mache:

void(&f)(int) = someFunction;
foo(std::move(f));

foo druckt:

void foo(T&&) [with T = void (&)int]

Das ist genau das gleiche wie zuvor! Was passiert hier? Warum ist das Ergebnis das gleiche wie beim Übergeben von lvalue? Ich würde erwarten, dass, da wir rvalue an foo übergeben, der hergeleitete Typ T = void (int) sein sollte und param zu void (&&) int werden sollte. Dies passiert immer bei allen anderen "normalen" Typen (wie Klassen, primitiven Typen usw.). Warum ist es anders, wenn es um Funktionsreferenzen geht?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage