Created on 2024-08-22.00:00:00 last changed 3 weeks ago
Proposed resolution:
This wording is relative to N4988.
Modify [optional.optional.general] as indicated:
[Drafting note: This edit modifies the same paragraph as issue 4015, but that other issue intentionally doesn't touch the affected sentence here (except for removing the italics on "contained value"). The intention is that the merge conflict can be resolved in the obvious way: "An optional object's contained value is nested within ([intro.object]) the optional object."]
-1- Any instance of
optional<T>
at any given time either contains a value or does not contain a value. When an instance ofoptional<T>
contains a value, it means that an object of typeT
, referred to as the optional object's contained value, isallocated within the storage ofnested within ([intro.object]) the optional object.Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value.When an object of typeoptional<T>
is contextually converted tobool
, the conversion returns `true` if the object contains a value; otherwise the conversion returns `false`.
Modify [variant.variant.general] as indicated:
-1- Any instance of
variant
at any given time either holds a value of one of its alternative types or holds no value. When an instance ofvariant
holds a value of alternative type `T`, it means that a value of typeT
, referred to as the `variant` object's contained value, isallocated within the storage ofnested within ([intro.object]) the `variant` object.Implementations are not permitted to use additional storage, such as dynamic memory, to allocate the contained value.
Modify [expected.object.general] as indicated:
-1- Any object of type
expected<T, E>
either contains a value of type `T` or a value of type `E`within its own storagenested within ([intro.object]) it.Implementations are not permitted to use additional storage, such as dynamic memory, to allocate the object of type `T` or the object of type `E`.Memberhas_val
indicates whether theexpected<T, E>
object contains an object of type `T`.
Modify [expected.void.general] as indicated:
-1- Any object of type
expected<T, E>
either represents a value of type `T`, or contains a value of type `E`within its own storagenested within ([intro.object]) it.Implementations are not permitted to use additional storage, such as dynamic memory, to allocate the object of type `E`.Memberhas_val
indicates whether theexpected<T, E>
represents a value of type `T`.
[ Wrocław 2024-11-23; Status changed: Voting → WP. ]
[ 2024-09-18; Reflector poll ]
Set status to Tentatively Ready after seven votes in favour during reflector poll.
This issue was split out from issue 4015.
`optional`, `variant` and `expected` all use similar wording to require their contained value to be a subobject, rather than dynamically allocated and referred to by a pointer, e.g.
When an instance ofoptional<T>
contains a value, it means that an object of typeT
, referred to as the optional object’s contained value, is allocated within the storage of the optional object. Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value.
During the LWG reviews of P2300 in St. Louis, concerns were raised about the form of this wording and whether it's normatively meaningful. Except for the special case of standard-layout class types, the standard has very few requirements on where or how storage for subobjects is allocated. The library should not be trying to dictate more than the language guarantees. It would be better to refer to wording from [intro.object] such as subobject, provides storage, or nested within. Any of these terms would provide the desired properties, without using different (and possibly inconsistent) terminology.
Using an array of bytes to provide storage for the contained value would make it tricky to meet the constexpr requirements of types like `optional`. This means in practice, the most restrictive of these terms, subobject, is probably accurate and the only plausible implementation strategy. However, I don't see any reason to outlaw other implementation strategies that might be possible in future (say, with a constexpr type cast, or non-standard compiler-specific instrinics). For this reason, the proposed resolution below uses nested within, which provides the desired guarantee without imposing additional restrictions on implementations.
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-11-28 21:40:31 | admin | set | messages: + msg14490 |
2024-11-28 21:40:31 | admin | set | status: voting -> wp |
2024-11-19 16:09:07 | admin | set | status: ready -> voting |
2024-09-18 22:27:23 | admin | set | messages: + msg14380 |
2024-09-18 22:27:23 | admin | set | status: new -> ready |
2024-08-22 11:55:32 | admin | set | messages: + msg14341 |
2024-08-22 00:00:00 | admin | create |