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
oversight.
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.
there are a lot of functions that are "just" missing the keyword due to
oversight.
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