Boost logo

Boost Users :

Subject: Re: [Boost-users] [boost.bind] How to retrieve the function type of aboost::bind result
From: Olaf Krzikalla (krzikalla_at_[hidden])
Date: 2009-01-27 14:23:38


Hi,

Peter Dimov wrote:
> Why not dispatch on the number of arguments that are available via
> getArg? You won't then need to know the arity of the function object
> (assuming it has one and only one arity, which it may not.)
I'm not sure if I understand you right.
The top level problem is to bind C++ functions in a generic way to LUA
script callbacks. That is I know the actual number of arguments not
before runtime. Below is my current solution (LUA specific stuff and the
rather obvious ArgTypeDispatcher are stripped):

---snip---

template<class T>
struct ArgNumDispatcher;

template<>
struct ArgNumDispatcher<boost::function<void()> >
{
   static void doFunction(const boost::function<void()>& f)
   {
     f();
   }
};

template<class T>
struct ArgNumDispatcher<boost::function<void(T)> >
{
   static void doFunction(const boost::function<void(T)>& f)
   {
     f(ArgTypeDispatcher<T, 0>::get());
   }
};

template<class T, class U>
struct ArgNumDispatcher<boost::function<void(T, U)> >
{
   static void doFunction(const boost::function<void(T, U)>& f)
   {
     f(ArgTypeDispatcher<T, 0>::get(),
       ArgTypeDispatcher<U, 1>::get());
   }
};

// aso.

struct tFunctionBase
{
   virtual void doFunction() = 0;
};

template<class T>
struct tFunction : tFunctionBase
{
   tFunction(const T& f) : func(f) {}
   virtual void doFunction()
   {
     int iNumArgs = getNumArguments(); //comes from LUA
     if (T::arity != iNumArgs)
     {
       //some error handling
     }

     ArgNumDispatcher<T>::doFunction(func);
   }
   T func;
};

std::map<std::string, boost::shared_ptr<tFunctionBase> > m_Functions;

template<class T>
void registerFunction(const std::string& strName,
                       boost::function<T> func)
{
   boost::shared_ptr<tFunctionBase> p
     (new tFunction<boost::function<T> >(func));
   m_Functions.insert(std::make_pair(strName, p));
}

---snip---

This works pretty well so far. However I can't squeeze out this last bit
of elegance by calling registerFunction with a bind expression and
without explicitely stating the function type in the template parameter.
But maybe there is a completely dfferent approach I don't see yet(?).

Thanks in advance
Olaf Krzikalla


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net