#include <iostream>
#include <functional>
using namespace std;
typedef int value;
template<class Signature>
function<void(int, value[])>
thunk( function<Signature> f );
template<class R, class Arg1>
function<void(int, value[])>
thunk( function<R(Arg1)> f )
{
return [f](int, value v[]) -> R
{
return f(v[0]);
};
}
template<class R, class Arg1, class Arg2>
function<void(int, value[])>
thunk( function<R(Arg1, Arg2)> f )
{
return [f](int, value v[]) -> R
{
return f(v[0], v[1]);
};
}
template<class R, class Arg1, class Arg2>
function<void(int, value[])>
thunk( R(*f)(Arg1, Arg2) )
{
return [f](int, value v[]) -> R
{
return f(v[0], v[1]);
};
}
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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0eXBlZGVmIGludCB2YWx1ZTsKCnRlbXBsYXRlPGNsYXNzIFNpZ25hdHVyZT4KZnVuY3Rpb248dm9pZChpbnQsIHZhbHVlW10pPgp0aHVuayggZnVuY3Rpb248U2lnbmF0dXJlPiBmICk7CgoKdGVtcGxhdGU8Y2xhc3MgUiwgY2xhc3MgQXJnMT4KZnVuY3Rpb248dm9pZChpbnQsIHZhbHVlW10pPgp0aHVuayggZnVuY3Rpb248UihBcmcxKT4gZiApCnsKCXJldHVybiBbZl0oaW50LCB2YWx1ZSB2W10pIC0+IFIKCXsKCQlyZXR1cm4gZih2WzBdKTsKCX07Cn0KCgp0ZW1wbGF0ZTxjbGFzcyBSLCBjbGFzcyBBcmcxLCBjbGFzcyBBcmcyPgpmdW5jdGlvbjx2b2lkKGludCwgdmFsdWVbXSk+CnRodW5rKCBmdW5jdGlvbjxSKEFyZzEsIEFyZzIpPiBmICkKewoJcmV0dXJuIFtmXShpbnQsIHZhbHVlIHZbXSkgLT4gUgoJewoJCXJldHVybiBmKHZbMF0sIHZbMV0pOwoJfTsKfQoKdGVtcGxhdGU8Y2xhc3MgUiwgY2xhc3MgQXJnMSwgY2xhc3MgQXJnMj4KZnVuY3Rpb248dm9pZChpbnQsIHZhbHVlW10pPgp0aHVuayggUigqZikoQXJnMSwgQXJnMikgKQp7CglyZXR1cm4gW2ZdKGludCwgdmFsdWUgdltdKSAtPiBSCgl7CgkJcmV0dXJuIGYodlswXSwgdlsxXSk7Cgl9Owp9CgoKdm9pZCBmMShpbnQgcDEpIHsgY291dCA8PCAiZjFcdCIgPDwgcDEgPDwgIlxuIjsgfQp2b2lkIGYyKGludCBwMSwgaW50IHAyKSB7IGNvdXQgPDwgImYyXHQiIDw8IHAxIDw8ICJcdCIgPDwgcDIgPDwgIlxuIjsgfQoKaW50IG1haW4oKSB7CglpbnQgYTFbXSA9IHsxfTsKCWludCBhMltdID0gezMsIDR9OwoJCgkvLyBjYXNlIDEKCWF1dG8gdWZ1bmMgPSB0aHVuayggZjIgKTsKCXVmdW5jKDIsYTIpOwoJCgoJLy8gY2FzZSAyCglhdXRvIGZmMiA9IFtdKGludCBwMSwgaW50IHAyKSB7IGNvdXQgPDwgImZmMlx0IiA8PCBwMSA8PCAiXHQiIDw8IHAyIDw8ICJcbiI7IH07CgkKCWF1dG8gdWZ1bmMyID0gdGh1bmsoIGZmMiApOwoJdWZ1bmMyKDIsYTIpOwoKCXJldHVybiAwOwp9
prog.cpp: In function ‘int main()’:
prog.cpp:60:27: error: no matching function for call to ‘thunk(main()::__lambda3&)’
auto ufunc2 = thunk( ff2 );
^
prog.cpp:60:27: note: candidates are:
prog.cpp:10:1: note: template<class Signature> std::function<void(int, int*)> thunk(std::function<Signature>)
thunk( function<Signature> f );
^
prog.cpp:10:1: note: template argument deduction/substitution failed:
prog.cpp:60:27: note: ‘main()::__lambda3’ is not derived from ‘std::function<Signature>’
auto ufunc2 = thunk( ff2 );
^
prog.cpp:15:1: note: template<class R, class Arg1> std::function<void(int, int*)> thunk(std::function<R(Arg1)>)
thunk( function<R(Arg1)> f )
^
prog.cpp:15:1: note: template argument deduction/substitution failed:
prog.cpp:60:27: note: ‘main()::__lambda3’ is not derived from ‘std::function<R(Arg1)>’
auto ufunc2 = thunk( ff2 );
^
prog.cpp:26:1: note: template<class R, class Arg1, class Arg2> std::function<void(int, int*)> thunk(std::function<R(Arg1, Arg2)>)
thunk( function<R(Arg1, Arg2)> f )
^
prog.cpp:26:1: note: template argument deduction/substitution failed:
prog.cpp:60:27: note: ‘main()::__lambda3’ is not derived from ‘std::function<R(Arg1, Arg2)>’
auto ufunc2 = thunk( ff2 );
^
prog.cpp:36:1: note: template<class R, class Arg1, class Arg2> std::function<void(int, int*)> thunk(R (*)(Arg1, Arg2))
thunk( R(*f)(Arg1, Arg2) )
^
prog.cpp:36:1: note: template argument deduction/substitution failed:
prog.cpp:60:27: note: mismatched types ‘R (*)(Arg1, Arg2)’ and ‘main()::__lambda3’
auto ufunc2 = thunk( ff2 );
^
prog.cpp:49:6: warning: unused variable ‘a1’ [-Wunused-variable]
int a1[] = {1};
^