Пожалуйста, сначала рассмотрите следующий пример (это часть кода с Cplusplus.com):
#include <iostream> // std::cout
#include <functional> // std::function, std::negate
int half(int x) {return x/2;}
int main () {
std::function<int(int)> fn1 = half; // function
std::function<int(int)> fn2 = ½ // function pointer
std::cout << "fn1(60): " << fn1(60) << '\n';
std::cout << "fn2(60): " << fn2(60) << '\n';
return 0;
}
Чем отличается fn1 от fn2 в примере?
Означает ли это, что fn1 скопирует функцию «наполовину», тогда как fn2 просто указывает на эту функцию.
Комментарии Cplusplus.com подразумевают, что они разные; но я слышал из какого-то видео, что они одинаковые, а оператор "&" просто необязателен.
Так что же правда? пожалуйста помоги.
В названии написано auto, а в коде написаноstd::function<int(int)>. Прими решение.
Неплохой идеей будет держаться подальше от cpluplus.com, так как это довольно мусор. Если это действительно не объясняет смысл этого примера, это явный признак чуши.
Только что поправил, всем спасибо :)
@molbdnilo, правда? Хотя все талантливые программисты на C++ родились оттуда :D (не включая меня, конечно)
@Crackie для хорошего справочного сайта C++ см.: cppreference.com.





Нет никакой практической разницы. Ссылка на функцию превращается в указатель, когда мы создаем из нее std::function.
В контекстах, где кажется, что произойдет копирование, ссылка немедленно превращается в указатель, как в C:
int main()
{
auto f1 = half;
auto f2 = ½
static_assert(std::is_same_v<decltype(f1),decltype(f2)>);
}
Однако на самом деле этого здесь не происходит, если исходить из основной части вопроса, а не из заголовка. std::function делает распад внутренне и явно.
Конструктор std::function принимает ссылку для пересылки, поэтому, если аргумент равен half, он будет принимать «ссылку lvalue на функцию», и не будет неявного преобразования функции в указатель (вместо этого конструктор делает это внутри, как требует его спецификация), и если аргумент равен &half, тогда он принимает «ссылку rvalue на указатель функции». Преобразование явно через &.
@ user17732522, исправил этот ответ - он кажется вам правильным?
Если typeSpecifier является объектом, то в большинстве случаев практической разницы нет. В вашем коде использование half и &half делает то же самое. Тем не менее стоит отметить, что здесь задействованы два разных эффекта:
auto f = function;
Это вызывает неявное преобразование function в объект, преобразование функции в указатель:
lvalue функционального типа T может быть преобразовано в prvalue типа «указатель на T». Результатом является указатель на функцию.
Обратите внимание, что ваш код не выполняет явное преобразование функции в указатель, потому что вы неявно вызываете следующий конструктор:
// You end up calling this with F = int(&)(int)
// i.e. a reference to a function taking int and returning int.
// (See https://cdecl.plus/?q=int%28%26%29%28int%29 for learning type syntax)
template<class F> function(F&& f);
Этот конструктор явно использует std::decay_t и выполняет внутреннее преобразование функции в указатель.
&auto f = &function;
Это явно принимает адрес функции:
Операнд унарного оператора
&должен быть lvalue некоторого типаT. Результатом является prvalue.
- [...]
- В противном случае результат имеет тип «указатель на
T» и указывает на обозначенный объект или функцию.
В вашем примере вы по-прежнему вызываете вышеупомянутый конструктор. Однако на этот раз вы передаете «указатель на функцию» int(*)(int) , а не «ссылку на функцию» int(&)(int). Конечный результат тот же.
спасибо @Ян Шультке
Вопрос в заголовке не соответствует коду в теле вопроса. В показанном коде нет
auto.