たとえば以下のコード、期待通りには動きません。
#include <iostream>
template<typename Function, typename T>
void do_it(Function f, T arg) { f(arg); }
int main() {
auto twice = [](int& x) { x *= 2; };
int n = 123;
do_it(twice, n); // nが2倍になる...
std::cout << n << std::endl;
}
ダメなんですね、do_itの第二引数には(int&ではなく)intが渡るのでnを書き換えることができません。
<functional>
に定義された ref, cref を通すことで 参照/const参照 を引き渡すことができます。
#include <iostream>
#include <functional>
template<typename Function, typename T>
void do_it(Function f, T arg) { f(arg); }
int main() {
auto twice = [](int& x) { x *= 2; };
int n = 123;
do_it(twice, std::ref(n)); // ← 参照を渡す!
std::cout << n << std::endl;
}