[C++-sig] bpl_utils explained

Ralf W. Grosse-Kunstleve rwgk at yahoo.com
Mon Jul 29 00:05:47 CEST 2002


--- David Abrahams <dave at boost-consulting.com> wrote:
> OK. Well, first, you just need to use registry::push_back to register this
> converter instead of registry::insert.
> ...
> Anyway, that will put
> register_container_from_python_sequence<T,some_policy> at the same priority
> as all implicit conversions, which is to say it will be at a lower priority
> than regular rvalue and lvalue conversions.

The availability of registry::push_back changes everything.

> > struct user
> > {
> >   void foo(std::vector<double> const& v);
> > };
> >
> > class_<user> ...
> >
> > Do you want a std::vector<int> to match the argument of foo()?
> 
> If class_<std::vector<int> > exposes enough interface to make it a
> sequence, I guess I do.

Of course I was thinking that both std::vector<int> and std::vector<double>
are exposed via class_<> . With the registry::push_back trick this
should now work as one expects.

> > Another situation:
> >
> > struct user
> > {
> >   void foo(std::vector<int> const& v);
> >   void foo(std::vector<double> const& v);
> > };
> >
> > What should happen now?
> 
> Well, here both functions match because our overload resolution mechanism
> is naive, so currently you get whichever one was registered last(?).

But if both std::vector<int> and std::vector<double> are exposed
via class_<> there is no ambiguity, right?

Please look at the new register_container_from_python_sequence::convertible
(everything else unchanged; except for the insert->push_back change).

Revised explanation:

Let obj be the object to be converted.

- obj is convertible only if it can be converted to an iterator
  (test is equivalent to iter(obj) in Python).

- Conversion policies are defined by a "registration_adaptor"
  struct (see bpl_utils.h).

- There are two fundamentally different conversion policies.
  Which one is used is determined by a static member function
  in the registration adaptors, e.g.:

  static bool check_convertibility_per_element() { return true; }

  false: no further checks are performed. convertible() returns true.

  true: obj is convertible only if PyObject_Length(obj) >= 0.

        PyObject_Length() is used to determine the size of the sequence
        and passed to the check_size() function of the registration
        adaptor. If this returns true, the sequence is traversed and
        extract<> is called for each element. obj is convertible only
        if the size check returns true and if all elements are
        convertible.

        As an optimization, if obj is a xrange object, only the first
        element is tested for convertibility.

        If overload resolution finally calls the construct()
        function, the obj is traversed a second time.

This is very nice and general and my tests all work fine. Could there
be any unpleasant surprises lurking?

Ralf


__________________________________________________
Do You Yahoo!?
Yahoo! Health - Feel better, live better
http://health.yahoo.com




More information about the Cplusplus-sig mailing list