std::function<void(const int&)> f = [](int a)
{
};
Разве не int и const int& разные типы?
Ответ 1
Они разные, но это не имеет значения, потому что аргумент const int& может быть передан параметру int, и это все, что требуется.
Ответ 2
Причиной вашего кода является то, что шаблонный конструктор std::function<R(Args...)>, берущий произвольный объект функции F, требует F для вызова с Args..., возвращающим R.
Требуется: F должен быть CopyConstructible. f должен быть доступен для типов аргументов ArgTypes и типа возврата R. [...]
Объектный объект, принимающий int, может быть вызван с помощью const int&, и, следовательно, этот код действителен и отвечает требованиям, поскольку оба возвращают void.