Зачем нужен амперсанд перед именем функции/метода?

Амперсанд (&) перед именем функции/метода в C++ имеет несколько различных значения и использований, которые зависят от контекста.

1. Определение ссылки на функцию:
Амперсанд может использоваться для определения ссылки на функцию. Например, следующий код создает ссылку на функцию add():

   int add(int a, int b) {
       return a + b;
   }
  
   int main() {
       int (*func)(int, int) = &add;
       int result = func(2, 3); // Здесь вызывается функция add() через указатель на функцию
       return 0;
   }

В данном случае, func - указатель на функцию типа int(int, int), и он инициализируется адресом функции add с использованием оператора &. Затем функция add вызывается через указатель на функцию func.

2. Передача функции в качестве аргумента:
В C++ функции также могут быть переданы в качестве аргумента в другие функции. Амперсанд используется для передачи функции вместо ее адреса. Например:

   int add(int a, int b) {
       return a + b;
   }

   int calculate(int x, int y, int (*func)(int, int)) {
       return func(x, y);
   }

   int main() {
       int result = calculate(2, 3, &add); // Здесь функция add передается как аргумент
       return 0;
   }

В данном случае, функция calculate принимает три аргумента - два целых числа (x и y) и указатель на функцию. Функция add передается в calculate как аргумент с использованием оператора &.

3. Использование в качестве оператора в объявлении и определении функции-члена класса:
В C++ амперсанд также используется как часть синтаксиса для объявления и определения функций-членов класса. Например:

   class MyClass {
   public:
       void myFunction() & {
           // Тело функции
       }
   };

В этом контексте амперсанд используется для указания, что данная функция-член является "ссылочной" функцией, то есть она может быть вызвана только для объектов, которые являются lvalue.

Обратите внимание, что когда амперсанд используется в объявлении указателя на функцию или передачи функции в качестве аргумента, его можно опустить. Такой код будет эквивалентен:

int (*func)(int, int) = &add;
int (*func)(int, int) = add;

int result = calculate(2, 3, &add);
int result = calculate(2, 3, add);

В целом, использование амперсанда перед именем функции/метода в C++ зависит от контекста и может иметь разные значения и использования. Это позволяет уточнить семантику функции-члена, объявить ссылку на функцию или передать функцию в качестве аргумента.