Вам необходимо изменить сигнатуры функций, чтобы принимать ссылки:
auto wrapper(int& i, F func) {...}
void f(int& i) {...}
, а также производить лямбда-захват по ссылке return [&]() { return func(i); };
. Тогда вам не нужно std::ref
.
Полный код будет выглядеть следующим образом:
#include <iostream>
#include <functional>
template<typename F>
auto wrapper(int& i, F func) {
return [&]() { return func(i); };
}
void f(int& i) {
std::cout << "i is " << i << '\n';
}
int main() {
int tmp = 1;
auto func = wrapper(tmp, f);
tmp = 2;
func();
}
Теперь приведенный выше код будет напечатан:
i is 2
Если вы все равно хотел бы использовать std::ref
, тогда ваша функция шаблона должна иметь следующую подпись:
template<typename F>
auto wrapper(std::reference_wrapper<int> i, F func) {...}