Лямбда-функция - это тип класса с одним оператором вызова функции.Таким образом, вы можете обнаружить арность этого оператора вызова функции, взяв его адрес и используя разрешение перегрузки, чтобы выбрать, какую функцию вызывать:
#include <iostream>
template<typename F,typename R>
void do_stuff(F& f,R (F::*mf)() const)
{
(f.*mf)();
}
template<typename F,typename R,typename A1>
void do_stuff(F& f,R (F::*mf)(A1) const)
{
(f.*mf)(99);
}
template<typename F,typename R,typename A1,typename A2>
void do_stuff(F& f,R (F::*mf)(A1,A2) const)
{
(f.*mf)(42,123);
}
template<typename F>
void do_stuff(F f)
{
do_stuff(f,&F::operator());
}
int main()
{
do_stuff([]{std::cout<<"no args"<<std::endl;});
do_stuff([](int a1){std::cout<<"1 args="<<a1<<std::endl;});
do_stuff([](int a1,int a2){std::cout<<"2 args="<<a1<<","<<a2<<std::endl;});
}
Будьте осторожны: это не будет работать с типами функций или классамитипы, которые имеют более одного оператора вызова функции или не const
операторы вызова функции.