Ravi wrote:
On Sunday 11 October 2009 19:44:29 troy d. straszheim wrote:
Why is the overloaded get_signature not picked up when it is declared
after  the inclusion of the headers?
I'm not sure why it isn't picked up.

Does that mean that you can reproduce the problem I pointed out?


Yes I can.

I've been working in this area, replacing most of detail/caller.hpp and detail/invoke.hpp with boost.fusion, seen here:

http://gitorious.org/~straszheim/boost/straszheim/blobs/python/boost/python
/detail/caller.hpp

In the process, I overhauled get_signature to use boost::function_types, and to be a metafunction, not a function:

http://gitorious.org/~straszheim/boost/straszheim/blobs/python/boost/python
/signature.hpp

IMHO, this is the right way to do it. This avoids relying on the compiler to optimize out all the ugly tag-dispatching. Of course, Dave A & Ralf WGK did not have function types when they wrote this originally.


Yes, the code was all dated ~2002. There are more corners of the code that could use modernization as well.

[snip]

   boost::function<int(X*, int)> bf0(fobj);

Why do you need to use boost::function here? Shouldn't the type be deduced automatically?


Note that the .def() of the various boost::function objects work without requiring the user to specialize get_signature, (since this modified get_signature metafunction knows about boost::function objects). Here's a different (working) example:

#include <boost/function.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/python.hpp>
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>

struct X { int y; };

struct add_to
{
  template <typename T>
  T operator()(X* x, T t) const
  {
    return t + x->y;
  }

  std::string operator()(X* x, std::string s)
  {
    return s + boost::lexical_cast<std::string>(x->y);
  }

};

using namespace boost::python;

BOOST_PYTHON_MODULE( function_objects_ext )
{
  add_to add_to_inst;
  boost::function<int(X*, int)> f_int(add_to_inst);
  boost::function<std::string(X*, std::string)> f_string(add_to_inst);

  boost::python::class_<X>( "X" )
    .def_readwrite( "y", &X::y )
    .def( "add_to", f_int)
    .def( "add_to", f_string)
    ;
}

>>> from function_objects_ext import *
>>> x = X()
>>> x.y = 13
>>> x.add_to(1)
14
>>> x.add_to("foo")
'foo13'

Some musings:

I think interoperability with boost::function is a Good Thing, but in the example above (and the previous), all it does is give def() a way to tell what the signature of the function object is at compile time, and it does so at a runtime cost. A specialization of get_signature works, but strikes me as kinda ugly (it should at least be moved out of 'detail' if it is a user customization point). How about something like

  class_<T>("T")
    .def("f1", f1, sig<void(T*, double)>)
    .def<void(T*, double)>("fi", f1)

Which looks pretty straightforward when dealing with function objects, but when dealing with overloads, things get tricky:

  void f2(T*, int);
  void f2(T*, double);

  class_<T>("T")
    .def("f2", f2)                     //  #1 error
    .def("f2", (void(*)(T*, int))f2)   //  #2 ok but ugly
    .def<void(T*, int)>("f2", f2)      //  #3 works but tricky
    ;

#1 is an error, because f2's type is undetermined.

#2 is how you can fix #1 in current practice (or with an alias).

#3 could work (I've tried, it works) if def, when passed a function type, only accepts pointers to functions of that type, so that the overload is resolved. But how to use this same form to also specify the types of arbitrary function objects... haven't thought about that yet.

I'm fairly new to the internals of boost.python, and only just now got this working... Do you see problems with this, specifically the conversion of get_signature from function to metafunction?

I don't see any problems with the conversion of get_signature to a metafunction. Do compile times get any longer?

I haven't checked this yet. I have other concerns re typechecking and automatic conversions... I'll go back and look more closely.

-t


_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to