Boost logo

Boost :

Subject: Re: [boost] [poly_collection] throws upon insertion
From: Joaquin M López Muñoz (joaquinlopezmunoz_at_[hidden])
Date: 2017-05-08 19:01:25


El 08/05/2017 a las 16:55, Andrzej Krzemienski via Boost escribió:
> In the class reference, I get:
> [...]
>
> (1) c.insert(x)
> (2) c.insert(it,x)
>
> Effects: If the type of the subobject of t is not registered, then if this
> type is T and T is acceptable, does the registration, otherwise throws. If
> t is not a non-const rvalue expression and the type of its subobject is not
> CopyConstructible, throws. Inserts an element with a subobject move
> constructed or copy constructed from the subobject of t: (1) at the end of
> the corresponding segment; (2) just before the position indicated by it, if
> it points to the corresponding segment, or at the end of the segment
> otherwise.
>
> [...]
>
> And maybe it is just me, but I cannot make the sense of it. First, it
> refers to 't' but in the signatures we have an 'x'. Next, the first
> sentence has two "if"s and one "otherwise" and I do not know which "if" the
> "otherwise" binds to. I read it as saying: if T is derived from the
> interface (like class `warrior`) but is not movable (which implies that T
> is not "acceptable"), then the program will compile fine but will later
> throw an exception. Is my interpretation correct? But if so, why not refuse
> to compile instead?

First of all the 't' bit is indeed a typo, it should be 'x'. As for the
intended meaning of this
admittedly awkard clause, this is:

   1. If the type of the subobject of x is not registered, then:
     1.1. if T is acceptable, does the registration, otherwise throws.
   2. If x is not a non-const rvalue expression and the type of its
subobject is
     not CopyConstructible, throws.
   3. Inserts an element constructed or copy constructed from the
subobject of x, etc.

So, going to your example, consider

   boost::base_collection<sprite> c;
   warrior w; // warrior is not moveable
   c.insert(w);

This throws because the "real" (most derived) type of w is warrior and
warrior is
not acceptable: why not just mark this as a compile error? Because of
the following:

   boost::base_collection<sprite> c;
   moveable_warrior mw; // derived from warrior and moveable
   c.register_types<moveable_warrior>(); // fine, moveable_warrior can
be registered
   warrior& w=mw;
   c.insert(w); // works!!

Insertion is succesful because the real type of w is a valid (and indeed
registered)
type. So we can't just SFINAE-supress warrior from the overload set of
insert().
Did I make my self clear?

I can try to reword the reference sections into a more digestible form.
Thanks for
spotting the typo!

Joaquín M López Muñoz


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk