C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Implementing a movable container for immovable objects: std::box<T>

From: Oskars Putans <o.putaans_at_[hidden]>
Date: Sat, 14 Dec 2024 23:36:20 +0200
> Container in C++ usually means something differently than what you use
it here

I agree, that's my mistake. I did not mean it as a container in the
classical sense. It's really a kind of smart pointer. I'm going to refer to
it as such from now on.

> You can have that type today with wrapping unique_ptr and removing some
methods, like release.

Of course. However if you have to both add and remove functionality, those
are grounds to make it a separate object.
As this is an even more strict unique_ptr, I would like to see it
implemented in the standard.
I believe more frequent usage of this could lead to safer code.

> How exactly this would not lead to an invalid state of box?
That is a fair point and something i had overlooked. This may have to be
changed to something similar to emplace, where a value is placed
in instead or this is available only on default-constructible items, so a
default value is placed inside.

> Swap is not semantics of any move constructor in standard library.
This does seem unconventional, yes, however, it does not seem to break the
standard as "Unless otherwise specified, all standard library objects that
have been moved from are placed in a "valid but unspecified state", meaning
the object's class invariants hold (so functions without preconditions,
such as the assignment operator, can be safely used on the object after it
was moved from)" (taken from cppreference.com)

> This just looks like bad design.
I agree, this isn't the cleanest thing. But for the purposes for this
proposal, I mentioned this to increase cohesion with the rest of the
standard library. You probably wouldn't use the box in cases where the C
function has a chance to leave the pointer empty. This case does seem a bit
niche, I can believe that.

sestd., 2024. g. 14. dec., plkst. 23:04 — lietotājs Ivan Matek (<
libbooze_at_[hidden]>) rakstīja:

> Not a C++ standards person, so dont take anything I say as likely to be
> correct, but here is my feedback:
>
> On Sat, Dec 14, 2024 at 9:31 PM Oskars Putans via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> This is my first time posting here, so I appreciate any guidance on the
>> style of my post.
>>
>> C++ has been progressively incorporating ideas from Rust to improve
>> memory safety. Easy examples are std::expected which parallel Rust's
>> Result, std::optional which parallels Rust's Option.
>>
>> I propose an adaptation of Rust's Box type: a pointer to a heap object
>> that always contains a valid value and allows the templated object to be an
>> incomplete type.
>>
>
>
>
> Container in C++ usually means something differently than what you use it
> here:
> https://en.cppreference.com/w/cpp/container
>
>>
>> First of all, I have to acknowledge that this type will most definitely
>> be a lot more restrictive than a std::unique_ptr.
>>
>> This container enforces two key invariants: (1) the internal pointer is
>> never nullptr and always points to an initialized value, and (2) the
>> contained value is immovable.
>> To upkeep the invariant that the contained heap value is valid, if there
>> is ever an invalid state,
>> an exception would be thrown immediately.
>>
>
> You can have that type today with wrapping unique_ptr and removing some
> methods, like release.
>
>
>>
>> Here's some of box's properties I've figured out so far (T being the
>> template type):
>>
>> - As a more constrained unique_ptr, it would be implicitly movable to a
>> unique_ptr.
>>
>
> How exactly this would not lead to an invalid state of box?
>
>
>>
>>
>
>> - Move constructor swaps the internal pointers to not have to perform any
>> extra initializations. Although this could be omitted from the standard and
>> let implementations decide how to perform the move while keeping or
>> discarding the invariant of the moved object. Either way should work well
>> enough. I haven't yet thought about how up-casting and down-casting would
>> function, but it shouldn't be too far from the way unique_ptr does that.
>>
>
> Swap is not semantics of any move constructor in standard library.
>
>>
>> - To facilitate interoperation with C libraries, support for
>> std::inout_ptr can be provided. std::inout_ptr would delete the object
>> and set the pointer to nullptr in case
>> This does risk breaking an invariant, but it would throw soon enough, and
>> anyone who uses this would immediately assume this is the place where an
>> invalid state is raised.
>>
>
> This just looks like bad design.
>
>
>

Received on 2024-12-14 21:36:33