Boost logo

Boost :

Subject: Re: [boost] [poly_collection] throws upon insertion
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2017-05-09 08:14:43


2017-05-08 21:01 GMT+02:00 Joaquin M López Muñoz via Boost <
boost_at_[hidden]>:

> 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
>

Thanks for the explanation. I get it now. Could I suggest some rewording of
the description of insert. Maybe first define something like 'ad-hoc
registration':

'ad-hoc registration' of a reference `t` of a static type `T` into
> collection `c` is defined as follows:
> * If the dynamic type of `t` is already registered in `c`: nothing,
> otherwise
> * if the dynamic type of `t` is `T` and `T` is acceptable in `c`:
> registers `T`, otherwise
> * throws exception of type `unregistered_type`.
>

Then in the effects clause of `insert` just use it:

Effects: performs ad-hoc registration of `t` into `*this`. Then, If `t` is
> not a ...
>

Regards,
&rzej;


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