#include <iostream>
#include <iostream>
#include <math.h>
template< class T, class Op >
struct Wrapper
{
Wrapper():t(nullptr){}
Wrapper( T* ptrT ):t(ptrT){}
Wrapper( Wrapper const& ) = default;
Wrapper& operator=( Wrapper const& ) = default;
template<class...Args>
auto operator()(Args&&...args) const->decltype( Op{}(std::declval<T*>(),std::declval<Args>()...)) {
return Op{}(t, std::forward<Args>(args)...);
}
T* t;
};
template< class T, bool isConst, class Sig >
struct MemberFunc;
template< class T, class R, class... Args >
struct MemberFunc<T, false, R(Args...) > {
template< R(T::*func)(Args...) >
struct type {
template<class... Ts>
R operator()(T* t, Ts&&...ts) const {
return (t->*func)(std::forward<Ts>(ts)...);
}
};
};
template< class T, class R, class... Args >
struct MemberFunc<T, true, R(Args...) > {
template< R(T::*func)(Args...) const >
struct type {
template<class... Ts>
R operator()(T const* t, Ts&&...ts) const {
return (t->*func)(std::forward<Ts>(ts)...);
}
};
};
struct kernel
{
double gauss( double s )
{
return exp(-0.5*s*s);
}
};
int main()
{
kernel G;
Wrapper<kernel, MemberFunc<kernel, false, double(double)>::type<&kernel::gauss>> myKernel(&G);
std::cout<< myKernel(0.0) <<std::endl;
std::cout<< myKernel(0.3) <<std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxtYXRoLmg+Cgp0ZW1wbGF0ZTwgY2xhc3MgVCwgY2xhc3MgT3AgPgpzdHJ1Y3QgV3JhcHBlcgp7CglXcmFwcGVyKCk6dChudWxscHRyKXt9CglXcmFwcGVyKCBUKiBwdHJUICk6dChwdHJUKXt9CglXcmFwcGVyKCBXcmFwcGVyIGNvbnN0JiApID0gZGVmYXVsdDsKCVdyYXBwZXImIG9wZXJhdG9yPSggV3JhcHBlciBjb25zdCYgKSA9IGRlZmF1bHQ7CgkKCXRlbXBsYXRlPGNsYXNzLi4uQXJncz4KCWF1dG8gb3BlcmF0b3IoKShBcmdzJiYuLi5hcmdzKSBjb25zdC0+ZGVjbHR5cGUoIE9we30oc3RkOjpkZWNsdmFsPFQqPigpLHN0ZDo6ZGVjbHZhbDxBcmdzPigpLi4uKSkgewoJCXJldHVybiBPcHt9KHQsIHN0ZDo6Zm9yd2FyZDxBcmdzPihhcmdzKS4uLik7Cgl9CglUKiB0Owp9OwoKdGVtcGxhdGU8IGNsYXNzIFQsIGJvb2wgaXNDb25zdCwgY2xhc3MgU2lnID4Kc3RydWN0IE1lbWJlckZ1bmM7CnRlbXBsYXRlPCBjbGFzcyBULCBjbGFzcyBSLCBjbGFzcy4uLiBBcmdzID4Kc3RydWN0IE1lbWJlckZ1bmM8VCwgZmFsc2UsIFIoQXJncy4uLikgPiB7Cgl0ZW1wbGF0ZTwgUihUOjoqZnVuYykoQXJncy4uLikgPgoJc3RydWN0IHR5cGUgewoJCXRlbXBsYXRlPGNsYXNzLi4uIFRzPgoJCVIgb3BlcmF0b3IoKShUKiB0LCBUcyYmLi4udHMpIGNvbnN0IHsKCQkJcmV0dXJuICh0LT4qZnVuYykoc3RkOjpmb3J3YXJkPFRzPih0cykuLi4pOwoJCX0KCX07Cn07CnRlbXBsYXRlPCBjbGFzcyBULCBjbGFzcyBSLCBjbGFzcy4uLiBBcmdzID4Kc3RydWN0IE1lbWJlckZ1bmM8VCwgdHJ1ZSwgUihBcmdzLi4uKSA+IHsKCXRlbXBsYXRlPCBSKFQ6OipmdW5jKShBcmdzLi4uKSBjb25zdCA+CglzdHJ1Y3QgdHlwZSB7CgkJdGVtcGxhdGU8Y2xhc3MuLi4gVHM+CgkJUiBvcGVyYXRvcigpKFQgY29uc3QqIHQsIFRzJiYuLi50cykgY29uc3QgewoJCQlyZXR1cm4gKHQtPipmdW5jKShzdGQ6OmZvcndhcmQ8VHM+KHRzKS4uLik7CgkJfQoJfTsKfTsKCnN0cnVjdCBrZXJuZWwKewogIGRvdWJsZSBnYXVzcyggZG91YmxlIHMgKQogIHsKICAgIHJldHVybiBleHAoLTAuNSpzKnMpOwogIH0KfTsKCmludCBtYWluKCkKewogIGtlcm5lbCBHOwoKICBXcmFwcGVyPGtlcm5lbCwgTWVtYmVyRnVuYzxrZXJuZWwsIGZhbHNlLCBkb3VibGUoZG91YmxlKT46OnR5cGU8Jmtlcm5lbDo6Z2F1c3M+PiBteUtlcm5lbCgmRyk7CgogIHN0ZDo6Y291dDw8IG15S2VybmVsKDAuMCkgPDxzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0PDwgbXlLZXJuZWwoMC4zKSA8PHN0ZDo6ZW5kbDsKCiAgcmV0dXJuIDA7Cn0=