Существует разница между функцией и указателем для функции.
Функции разные, потому что они не являются объектами (в стандартном смысле слова). Нет такой функции, как function rvalues (за пределами определенных странных случаев, связанных с нестационарными функциями-членами). Фактически, rvalue ссылается на функцию: lvalues ли или нет.
Указатели на функции, ну, указатели, которые являются объектами. У вас может быть указатель на указатель на тип функции или значение x для указателя на тип функции или lvalue указателя на тип функции. &function
создает указатель prvalue для функции; в void (*f)() = function;
преобразование функции в указатель применяется для преобразования функции lvalue function
в указатель prvalue для функции, с которой инициализируется f
.
Теперь рассмотрит этот набор перегрузок:
template <typename RET_TYPE, typename...ARGs>
void takeFunctionRef(RET_TYPE(&& /*function*/)(ARGs...)) // #1
{
std::cout << "RValue function" << std::endl;
}
template <typename RET_TYPE, typename...ARGs>
void takeFunctionRef(RET_TYPE(& /*function*/)(ARGs...)) // #2
{
std::cout << "LValue function" << std::endl;
}
takeFunctionRef(function); // calls #2
takeFunctionRef(std::move(function)); // still calls #2!
перегрузка # 2 выбран из специального тай-брейка в [over.ics.rank], пуля 3.1.4, что способствует связыванию Lvalue ссылки на функцию lvalue по привязке ссылки rvalue к функции lvalue. Но оба будут успешно связываться (т. Е. Если вы удалите # 2, вы увидите # 1, вызываемый в обоих случаях).
Полагает, что первая является ссылкой на функцию, а вторая - ссылкой на указатель функции. – Galik