[C++-sig] bpl_utils explained

David Abrahams dave at boost-consulting.com
Mon Jul 29 09:11:03 CEST 2002


-----------------------------------------------------------
           David Abrahams * Boost Consulting
dave at boost-consulting.com * http://www.boost-consulting.com


----- Original Message -----
From: "Ralf W. Grosse-Kunstleve" <rwgk at yahoo.com>
To: <c++-sig at python.org>
Sent: Monday, July 29, 2002 2:27 AM
Subject: Re: [C++-sig] bpl_utils explained


> --- David Abrahams <dave at boost-consulting.com> wrote:
> > If each one exposes a sequence interface, and if the presence of a
sequence
> > interface and convertible elements is enough for your from_python
converter
> > to report convertibility, then I think there is ambiguity. Although
there
> > is a crude priority system for converter matching (rvalue converters
that
> > have been "pushed back" are considered last for arguments for which
rvalue
> > conversions are eligible -- T, T const&), the system for function
overload
> > matching is still first-come, first-served.
>
> Sorry, you lost me here.
> Let's call the "inserted" converters class 1 converters, and the
> "pushed back" converters class 2 converters.

Not to confuse things here, but within class 1 we have subcategories of
lvalue and rvalue converters (class 2 is only rvalue converters).

> Isn't it that all converters generated via class_<> are class 1
> converters?

Yes, they are in fact lvalue converters.

> Isn't it that overload resolution /always/ tests /all/ class 1
> converters before resorting to class 2 converters?

For each overload, yes. In other words, each overload is considered
separately. If an overload for which matches using a class 2 converter is
considered first, it won't matter that another overload can match using a
class 1 converter. That's what I mean by "naive overload resolution".

> Now let's say overload resolution is trying to match
>
> void foo(std::vector<int> const& v)
>
> Say there is only this one foo() (IOW no other overloads).
> For the conversion to succeed there has to be at least one registered
> std::vector<int> converter, either class 1 or class 2. If there is only
> a class 2, the Python object to be converted cannot be a wrapped
> std::vector<int> .
> Right?

Not neccessarily. You could create a class 2 converter which converts from
wrapped std::vector<int> to std::vector<int>. In fact, I think

    implicitly_convertible<std::vector<int>, std::vector<int> >();

would be enough to do it. However, barring such perversity, you are right.

> If there is a class1 converter, the Python object to be converted could
> be a std::vector<int>, and if it is, it will be converted with the class
1
> converter.
> Right?

Right.

> If the Python object to be converted is not a std::vector<int> but
> it is a sequence (measurable or not measurable, depending on
> "check_convertibility_per_element"), it will be converted by the
> class 2 converter.
> Right?

Right.

> Now lets look at this:
>
> void foo(std::vector<int> const& v)
> void foo(std::vector<double> const& v)
>
> If both vector types have a class 1 converter there is no ambiguity.
> Right?

I'm not sure whether by "class 1" you mean the specific converters which
are currently inserted, or any converter which is allowed to be inserted.
Since there's nothing stopping you from using insert on any particular
converter, I guess your statement above is false (in general).

Here's a statement which is true:

    If both types have ONLY an lvalue converter there is no ambiguity.

> If both have only a class 2 converter the ambiguity is exactly
> equivalent to this situation:
>
> void foo(int)
> void foo(double)
>
> The overload that is tried first during overload resolution is used.
> Right?

Right.

> Now say std::vector<int> is class 1 & 2 convertible, and
> std::vector<double> only class 2. If the object to be converted
> is a wrapped std::vector<int> it will be converted class 1,
> otherwise the overload tried first will be used.

That would be nice, but it ain't so. If the vector<double> overload is
tried first it will match, and overload resolution will stop there.

> If this is all correct, then I conclude that there is nothing new to
> learn for Boost Python users. Just as we cannot be sure if we get
> foo(int) or foo(double) until we know the order in which the converters
> were registered we cannot be sure if we get foo(std::vector<int>) or
> foo(std::vector<double>) if the class 1 vector containers are missing.
> Other than that the conversions are "predictable" without having to know
the
> order of registration.
> Correct?

Nope. FWIW, Even if that were the case, I'm not satisfied with having an
ordering dependency on converter registration.

> > IOW, function overloads are considered in sequence, and the first one
for
> > which all arguments find converters is called.
>
> Is my conclusion above what you mean?

No :(

> > I'm not sure I'm looking in the right place.
> >
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cctbx/cctbx/misc/?only_with_
> > tag=boost_python_v2_transition shows the most recent change 27 hours
ago...
>
> cvs -z3 -d:pserver:anonymous at cvs.cctbx.sourceforge.net:/cvsroot/cctbx
co -r
> boost_python_v2_transition cctbx
>
> cctbx/include/cctbx/bpl_utils.h
> cctbx/misc
>
> cctbx/include/cctbx/array_family/shared_bpl.h
> cctbx/arraytbx/shared*.cpp
>
> > >   static bool check_convertibility_per_element() { return true; }
> >
> > Hmm, wouldn't it be better to do this with something that could be
> > evaluated at compile time? That would guarantee avoiding generating
code
> > for the check in the case where it was false.
>
> After you move my stuff to the library I will check how you get this
> to work without compile-time warnings ("unreachable code").

I doubt I'm going to be able to do any of this before I get back from
vacation. I'm trying to prepare to teach a class in Oregon on Tuesday and
I'm running out of time.

Thanks, though: I mean it!

-Dave






More information about the Cplusplus-sig mailing list