#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;
}