#include <iostream>
#include <functional>
using namespace std;
typedef int value;
// для одного аргумента
// Констатнтый метод - и лямбда и std::function идут сюда
template<class F, class R, class Arg1>
function<void(int, value[])>
thunk_impl( F f, R(F::*)(Arg1) const )
{
return [f](int, value v[]) -> R
{
return f(v[0]);
};
}
// Неконстантный метод
template<class F, class R, class Arg1>
function<void(int, value[])>
thunk_impl( F f, R(F::*)(Arg1) )
{
return [f](int, value v[]) -> R
{
return f(v[0]);
};
}
// Свободная функция
template<class F, class R, class Arg1>
function<void(int, value[])>
thunk_impl( F f, R(Arg1) )
{
return [f](int, value v[]) -> R
{
return f(v[0]);
};
}
// для двух аргументов
// Констатнтый метод - и лямбда и std::function идут сюда
template<class F, class R, class Arg1, class Arg2>
function<void(int, value[])>
thunk_impl( F f, R(F::*)(Arg1, Arg2) const )
{
return [f](int, value v[]) -> R
{
return f(v[0], v[1]);
};
}
// Неконстантный метод
template<class F, class R, class Arg1, class Arg2>
function<void(int, value[])>
thunk_impl( F f, R(F::*)(Arg1, Arg2) )
{
return [f](int, value v[]) -> R
{
return f(v[0], v[1]);
};
}
// Свободная функция
template<class F, class R, class Arg1, class Arg2>
function<void(int, value[])>
thunk_impl( F f, R(Arg1, Arg2) )
{
return [f](int, value v[]) -> R
{
return f(v[0], v[1]);
};
}
// и так далее...
// Методы
template<class F>
function<void(int, value[])>
thunk( F f )
{
return thunk_impl<F>(f, &F::operator());
}
// Указатели на функции
template<class F>
function<void(int, value[])>
thunk( F* f )
{
return thunk_impl<F*>(f, f);
}
void f1(int p1) { cout << "f1\t" << p1 << "\n"; }
void f2(int p1, int p2) { cout << "f2\t" << p1 << "\t" << p2 << "\n"; }
int main() {
//int a1[] = {1};
int a2[] = {3, 4};
// case 1
auto ufunc = thunk( f2 );
ufunc(2,a2);
// case 2
auto ff2 = [](int p1, int p2) { cout << "ff2\t" << p1 << "\t" << p2 << "\n"; };
auto ufunc2 = thunk( ff2 );
ufunc2(2,a2);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0eXBlZGVmIGludCB2YWx1ZTsKCi8vINC00LvRjyDQvtC00L3QvtCz0L4g0LDRgNCz0YPQvNC10L3RgtCwCgoKLy8g0JrQvtC90YHRgtCw0YLQvdGC0YvQuSDQvNC10YLQvtC0IC0g0Lgg0LvRj9C80LHQtNCwINC4IHN0ZDo6ZnVuY3Rpb24g0LjQtNGD0YIg0YHRjtC00LAKdGVtcGxhdGU8Y2xhc3MgRiwgY2xhc3MgUiwgY2xhc3MgQXJnMT4KZnVuY3Rpb248dm9pZChpbnQsIHZhbHVlW10pPgp0aHVua19pbXBsKCBGIGYsIFIoRjo6KikoQXJnMSkgY29uc3QgICkKewogICAgcmV0dXJuIFtmXShpbnQsIHZhbHVlIHZbXSkgLT4gUgogICAgewogICAgICAgIHJldHVybiBmKHZbMF0pOwogICAgfTsKfQoKLy8g0J3QtdC60L7QvdGB0YLQsNC90YLQvdGL0Lkg0LzQtdGC0L7QtAp0ZW1wbGF0ZTxjbGFzcyBGLCBjbGFzcyBSLCBjbGFzcyBBcmcxPgpmdW5jdGlvbjx2b2lkKGludCwgdmFsdWVbXSk+CnRodW5rX2ltcGwoIEYgZiwgUihGOjoqKShBcmcxKSApCnsKICAgIHJldHVybiBbZl0oaW50LCB2YWx1ZSB2W10pIC0+IFIKICAgIHsKICAgICAgICByZXR1cm4gZih2WzBdKTsKICAgIH07Cn0KCi8vINCh0LLQvtCx0L7QtNC90LDRjyDRhNGD0L3QutGG0LjRjwp0ZW1wbGF0ZTxjbGFzcyBGLCBjbGFzcyBSLCBjbGFzcyBBcmcxPgpmdW5jdGlvbjx2b2lkKGludCwgdmFsdWVbXSk+CnRodW5rX2ltcGwoIEYgZiwgUihBcmcxKSApCnsKICAgIHJldHVybiBbZl0oaW50LCB2YWx1ZSB2W10pIC0+IFIKICAgIHsKICAgICAgICByZXR1cm4gZih2WzBdKTsKICAgIH07Cn0KCi8vINC00LvRjyDQtNCy0YPRhSDQsNGA0LPRg9C80LXQvdGC0L7QsgoKLy8g0JrQvtC90YHRgtCw0YLQvdGC0YvQuSDQvNC10YLQvtC0IC0g0Lgg0LvRj9C80LHQtNCwINC4IHN0ZDo6ZnVuY3Rpb24g0LjQtNGD0YIg0YHRjtC00LAKdGVtcGxhdGU8Y2xhc3MgRiwgY2xhc3MgUiwgY2xhc3MgQXJnMSwgY2xhc3MgQXJnMj4KZnVuY3Rpb248dm9pZChpbnQsIHZhbHVlW10pPgp0aHVua19pbXBsKCBGIGYsIFIoRjo6KikoQXJnMSwgQXJnMikgY29uc3QgKQp7CiAgICByZXR1cm4gW2ZdKGludCwgdmFsdWUgdltdKSAtPiBSCiAgICB7CiAgICAgICAgcmV0dXJuIGYodlswXSwgdlsxXSk7CiAgICB9Owp9CgovLyDQndC10LrQvtC90YHRgtCw0L3RgtC90YvQuSDQvNC10YLQvtC0CnRlbXBsYXRlPGNsYXNzIEYsIGNsYXNzIFIsIGNsYXNzIEFyZzEsIGNsYXNzIEFyZzI+CmZ1bmN0aW9uPHZvaWQoaW50LCB2YWx1ZVtdKT4KdGh1bmtfaW1wbCggRiBmLCBSKEY6OiopKEFyZzEsIEFyZzIpICkKewogICAgcmV0dXJuIFtmXShpbnQsIHZhbHVlIHZbXSkgLT4gUgogICAgewogICAgICAgIHJldHVybiBmKHZbMF0sIHZbMV0pOwogICAgfTsKfQoKLy8g0KHQstC+0LHQvtC00L3QsNGPINGE0YPQvdC60YbQuNGPCnRlbXBsYXRlPGNsYXNzIEYsIGNsYXNzIFIsIGNsYXNzIEFyZzEsIGNsYXNzIEFyZzI+CmZ1bmN0aW9uPHZvaWQoaW50LCB2YWx1ZVtdKT4KdGh1bmtfaW1wbCggRiBmLCBSKEFyZzEsIEFyZzIpICkKewogICAgcmV0dXJuIFtmXShpbnQsIHZhbHVlIHZbXSkgLT4gUgogICAgewogICAgICAgIHJldHVybiBmKHZbMF0sIHZbMV0pOwogICAgfTsKfQoKCi8vINC4INGC0LDQuiDQtNCw0LvQtdC1Li4uCgovLyDQnNC10YLQvtC00YsKdGVtcGxhdGU8Y2xhc3MgRj4KZnVuY3Rpb248dm9pZChpbnQsIHZhbHVlW10pPgp0aHVuayggRiBmICkKewoJcmV0dXJuIHRodW5rX2ltcGw8Rj4oZiwgJkY6Om9wZXJhdG9yKCkpOwp9CgoKLy8g0KPQutCw0LfQsNGC0LXQu9C4INC90LAg0YTRg9C90LrRhtC40LgKdGVtcGxhdGU8Y2xhc3MgRj4KZnVuY3Rpb248dm9pZChpbnQsIHZhbHVlW10pPgp0aHVuayggRiogZiApCnsKCXJldHVybiB0aHVua19pbXBsPEYqPihmLCBmKTsKfQoKdm9pZCBmMShpbnQgcDEpIHsgY291dCA8PCAiZjFcdCIgPDwgcDEgPDwgIlxuIjsgfQp2b2lkIGYyKGludCBwMSwgaW50IHAyKSB7IGNvdXQgPDwgImYyXHQiIDw8IHAxIDw8ICJcdCIgPDwgcDIgPDwgIlxuIjsgfQoKaW50IG1haW4oKSB7CgkvL2ludCBhMVtdID0gezF9OwoJaW50IGEyW10gPSB7MywgNH07CgkKCS8vIGNhc2UgMQoJYXV0byB1ZnVuYyA9IHRodW5rKCBmMiApOwoJdWZ1bmMoMixhMik7CgkKCgkvLyBjYXNlIDIKCWF1dG8gZmYyID0gW10oaW50IHAxLCBpbnQgcDIpIHsgY291dCA8PCAiZmYyXHQiIDw8IHAxIDw8ICJcdCIgPDwgcDIgPDwgIlxuIjsgfTsKCQoJYXV0byB1ZnVuYzIgPSB0aHVuayggZmYyICk7Cgl1ZnVuYzIoMixhMik7CgoJcmV0dXJuIDA7Cn0=