C++ Logo


Advanced search

std::optional - Inconsistency/defect regarding constexpr

From: Michael Scire <sciresm_at_[hidden]>
Date: Thu, 24 Sep 2020 01:12:20 -0700
The rules surrounding constexpr for std::optional seem inconsistent -- like
there are a lot of functions that are "just" missing the keyword due to

For example, `optional(std::nullopt_t)` is constexpr, but `optional
&operator=(std::nullopt_t)` is not.

This leads to the following (https://godbolt.org/z/8a9Ga3):

// Okay
constexpr std::optional<int> ValidOptional = []{
    std::optional<int> opt(std::nullopt);
    opt = std::optional<int>(std::nullopt);
    return opt;

// Compiler error
constexpr std::optional<int> InvalidOptional = []{
    std::optional<int> opt(std::nullopt);
    opt = std::nullopt;
    return opt;

Other oversights:
`template<typename U> optional(U &&)` is constexpr, but `template<typename
U> optional &operator=(U &&)` is not.

Things that are less obviously oversights, but might want to change:
`emplace` is not constexpr, even though the constructors it would call are.
`reset` is not constexpr.
`swap(optional &)` is not constexpr, nor is std::swap for optionals.
(std::swap is constexpr for other types).
copy constructor/move constructor for template<typename T> optional<U> are
not constexpr, even though optional(U &&) is.
If the following changed, copy/move assignment operators would probably
also want to be constexpr.

Received on 2020-09-24 03:12:36