Template wrapper for constant and non-const member functions of arbitrary classes

I want to have a template class (wrapper) that can take all possible classes (T) and do things (evaluated here) using member functions of these classes (function).

I found similar queries that you see here here and here , but none of them could satisfy the two below.

Conditions:

  • Both pointers to a class instance (T * ptr) and a pointer to a member function (function) must be available in the shell class.

  • A wrapper class should work with both constant and non-constant member functions.

Here is code that only works for non const:

#include <iostream>
#include <math.h>

template< class T, double (T::*fck) (double) >
struct Wrapper
{
  Wrapper( T * ptrT);

  double evaluate( double );

protected:

  T * myPtrT;
};


template< class T, double (T::*fck) (double) >
Wrapper<T, fck>::Wrapper( T * ptrT) : myPtrT(ptrT) {}


template< class T, double (T::*fck) (double) >
double Wrapper<T, fck>::evaluate( double s )
{ return (myPtrT->*fck)(s); }


struct kernel
{
  double gauss( double s )
  {
    return exp(-0.5*s*s);
  }
};

int main()
{
  kernel G;

  Wrapper<kernel, &kernel::gauss> myKernel ( &G );

  std::cout<< myKernel.evaluate(0.0) <<std::endl;
  std::cout<< myKernel.evaluate(0.3) <<std::endl;

  return 0;
}
+4
2

Wrapper ? , , : double f(double). std::function (++ 11) boost::function (++ 03).

boost::function boost::bind ++ 03:

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <math.h>

struct kernel
{
  double gauss( double s )
  {
    return exp(-0.5*s*s);
  }
};

int main()
{
    kernel G;

    typedef boost::function<double (double)> MyWrapper;

    MyWrapper w( boost::bind(&kernel::gauss, G, _1) );
    std::cout << w(0.0) << std::endl;
    std::cout << w(0.3) << std::endl;

    return 0;
}
+3

, .

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

MemberFunc::type std::mem_fun.

Wrapper , . MemberFunc<...>::type<...> , -.

.evaluate - invokation, , , .

, :

auto myKernel = [G](double s)->double { return G->gauss( s ); };

myKernel . - , .

std::function , , .

+2

All Articles