C++ Logo

std-proposals

Advanced search

Re: [std-proposals] zero overhead for std::optional

From: Andre Kostur <andre_at_[hidden]>
Date: Sun, 5 Apr 2026 07:47:40 -0700
On Sun, Apr 5, 2026 at 7:15 AM Arthur O'Dwyer via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> On Sat, Apr 4, 2026 at 6:19 AM Peter Neiss via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> Hello,
>>
>> the std::optional as it is today has an overhead flaw with the additional bool in the implementation to check if a value is there. In a lot of major and important cases this is suboptimal. (It is necessary for the general case).
>> Principal example are pointers which have a NULL that is traditionally used to mark them as "not value".
>
>
> Pointers in particular are a bad example, because if you need
> - "A thing that maybe holds the address of an object, or maybe doesn't (and we physically represent the latter state by all-bits-zero),"
> then you can just use `T*` directly. You don't need the `optional` part at all.
> And C++26 introduces `optional<T&>` with the same semantics and physical representation.
>
> You seem to want to make it so that an engaged `optional<X>` holds an X without some particular value, and a disengaged `optional<X>` holds an X with that particular value. That's never going to fly, because the point of a disengaged optional is that it does not hold an X. A disengaged optional<X> should be cheap to construct (notably it should not call the user-defined `X::X()`) and cheap to destroy (notably it should not call the user-defined `X::~X()`) — because a disengaged optional<X> should not hold an X to begin with!

That doesn't seem to be my interpretation of the proposal, at least
from the user's perspective. A disengaged optional<X> with a valid X
of a particular value would be indisinguishable a disengaged
optional<X> that does not contain a valid X. Hopefully the types
being used with this new optional are themselves cheap to construct
(the examples given of a raw pointer, file descriptor, et al certainly
are), but it is not guaranteed. One could provide an arbitrarily
complex X as long as it has a sentinel value. Though to be fair: code
which is intended to be improved by this proposal is already paying
for that expensive lifetime management since it is currently working
directly with the sentinel values.

The value that I see in this proposal has more to do with the code
correctness aspect: the sentinel value can no longer be used as a
valid value. Attempting to .value() on it would be a bad optional
access. Blind dereference is already UB if the optional is
disengaged.

I'm kinda thinking whether this should be framed more as a wrapper
around a type with a sentinel value instead of an extension of
optional, even if it has an API guided from optional.

Received on 2026-04-05 14:47:53