3196. std::optional<T> is ill-formed is T is an array

Section: 22.5.3 [optional.optional] Status: C++20 Submitter: Jonathan Wakely Opened: 2019-03-18 Last modified: 2021-02-25

Priority: 0

View all other issues in [optional.optional].

View all issues with C++20 status.

Discussion:

22.5.3 [optional.optional] appears to allow arrays:

T shall be an object type other than cv in_place_t or cv nullopt_t and shall satisfy the Cpp17Destructible requirements (Table 30).

But instantiating it fails, because value_or attempts to return T by value, which isn't possible for an array type.

Existing practice seems to be to reject array types. Libstdc++ and libc++ give an error for the signature of value_or, and MSVC fails a static assert saying the type needs to be destructible (which is misleading, because int[2] is destructible, but either way it's ill-formed).

Previous resolution [SUPERSEDED]:

This wording is relative to N4810.

  1. Modify 22.5.3 [optional.optional] as indicated:

    -3- T shall be an non-array object type other than cv in_place_t or cv nullopt_t and shall satisfy the Cpp17Destructible requirements (Table 30).

[2019-03-26 Marshall provides updated resolution based on reflector discussion]

[2019-06-16 Moved to "Tentatively Ready" based on five positive votes on the reflector]

Proposed resolution:

This wording is relative to N4810.

  1. In 16.4.4.2 [utility.arg.requirements], edit Table 30 — "Cpp17Destructible requirements" as indicated:

    Table 30 — Cpp17Destructible requirements
    Expression Post-condition
    u.~T() All resources owned by u are reclaimed, no exception is propagated.
    [Note: Array types and non-object types are not Cpp17Destructible. — end note]
  1. Modify 22.5.3 [optional.optional] as indicated:

    -3- T shall be a object type other than cv in_place_t or cv nullopt_t and shall satisfythat meets the Cpp17Destructible requirements (Table 30).

  1. Modify 22.6.3 [variant.variant] as indicated:

    -2-All types in Types shall be (possibly cv-qualified) object types that are not arraysmeet the Cpp17Destructible requirements (Table 30).