[C++-sig] bpl_utils explained

David Abrahams dave at boost-consulting.com
Sun Jul 28 15:13:01 CEST 2002


From: "Ralf W. Grosse-Kunstleve" <rwgk at yahoo.com>

> --- David Abrahams <dave at boost-consulting.com> wrote:
> > I'm appreciative of all the work you've been doing, so please don't
take
> > this the wrong way: I don't understand why the simple change of using a
> > pointer or non-const reference as the first argument to one of your
> > functions instead of a const reference is distasteful enough to warrant
> > removing conversion from general sequences. That seems like a pretty
> > radical change to make for the sake of the style of what is essentially
an
> > implementation detail.
>
> The short answer:
>
> The "simple change" did not seem generally applicable to me. People will
> have code like:
>
> struct user
> {
>   void foo(std::vector<double> const& v);
> };
>

You're right of course. I realized why this would be an issue the moment I
woke up this morning ;-).

However, I think I have a solution for you (it was there, lurking, all
along)...

> The longer answer:
>
> Users will want to know:
>
> How does overload resolution work if you have both a class_<T> and
> register_container_from_python_sequence<T, some_policy>?


OK. Well, first, you just need to use registry::push_back to register this
converter instead of registry::insert. That is the hack used by
implicitly_covertible<T,U> to make these conversions lowest-priority. I
think of the conversion you're registering the same way: it is determined
that some some C++ rvalue T can be extracted in the convertible step, then
in the convert step it is extracted  and converted to U.

In this case, the analogous T is a type we haven't yet actually written
called "sequence" which can be built from any sequence.

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.

> (where T is e.g. std::vector<U> or std::list<U>)
>
> My previous posting gives /an/ answer that I thought a wider audience
> can absorb and work with.

I understand why you did that.

> Could you please modify the explanation under
> "true" and "false" to reflect what you'd like to see? I could then
> try the implementation.
>
> Say you have
>
> class_<std::vector<int> > ...
> register_container_from_python_sequence<
>   std::vector<int>,
>   variable_size_container_registration_adaptor>();
>
> class_<std::vector<double> > ...
> register_container_from_python_sequence<
>   std::vector<double>,
>   variable_size_container_registration_adaptor>();
>
> 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.

> 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(?).

I just want to stress that this is a problem with the formulation of BPL
overload resolution. I'd really REALLY like to address this. However, I'll
need other people to participate in thinking about how it should work at a
high level (not implementation details) in order to come up with something.
The question is basically this: what should the prioritization rule be when
multiple overloaded functions match?

When I brought this up on python-dev, Guido sent me over to the types-sig,
where it met with a deathly silence:
http://aspn.activestate.com/ASPN/Mail/Message/types-sig/1222793. Turns out
the types-sig is effectively dead. He claims this wasn't an attempt to kill
the conversation, but I have my doubts<wink>.

If anyone is ready to discuss this in the context of C++, so am I...

-Dave

> P.S.: I've remove my as_tuple() function because tuple() (or list() or
> iter()) does the job anyway:

Nice!


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






More information about the Cplusplus-sig mailing list