[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