Лучший способ - явно создать объект std::function
правильного типа, а затем передать этот объект в функцию:
std::function<void(int, int)> func =
[](int a, int b) { cout << "a: " << a << " b: " << b << endl; }
foo(func);
или встроенный:
foo(
std::function<void(int, int)>(
[](int a, int b) { cout << "a: " << a << "b: " << b << endl; }
));
std::function
имеет шаблон конструктора, который принимает все:
template<class F> function(F);
Из-за этого у компилятора нет возможности узнать во время разрешения перегрузки, что foo
можно выбрать: и std::function<void(int)>
, и std::function<void(int, int)>
имеют конструктор, который может принимать ваше лямбда-выражение в качестве аргумента.
При непосредственной передаче объекта std::function
конструктор копирования std::function
предпочтительнее при разрешении перегрузки, поэтому он выбирается вместо шаблона конструктора.
Ответ на будущее: Если список захвата гарантированно будет пустым, вы также можете использовать обычные указатели на функции. В C ++ 0x лямбда без захвата неявно преобразуется в указатель на функцию. Таким образом, вы можете использовать что-то вроде
void foo(void (*t)(int, int)) { t(1, 2); }
void foo(void (*t)(int)) { t(1); }
и вызов foo
напрямую с лямбда без захвата (или указатель на функцию с соответствующим типом).
Обратите внимание, что это преобразование является очень недавним дополнением к черновому стандарту языка (оно было добавлено в феврале этого года), поэтому вряд ли оно пока получит широкую поддержку. Visual C ++ 2010 пока не поддерживает его; Я не знаю о последних g ++.