constexpr Optional в С++17 не компилируется
template <typename T>
struct Optional {
constexpr Optional() : has_value_{false} { }
constexpr auto has_value() const -> bool { return has_value_; }
union {
T value;
};
bool has_value_;
};
static_assert(not Optional<int>{}.has_value());
Почему код не компилируется в C++17, но компилируется в C++20?
error: non-constant condition for static assertion
Ответы (1 шт):
Автор решения: Chorkov
→ Ссылка
gcc ругается более понятно:
<source>:13:15: error: non-constant condition for static assertion
13 | static_assert(not Optional<int>{}.has_value());
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:13:15: error: 'constexpr Optional<T>::Optional() [with T = int]' called in a constant expression
<source>:3:15: note: 'constexpr Optional<T>::Optional() [with T = int]' is not usable as a 'constexpr' function because:
3 | constexpr Optional() : has_value_{false} { }
| ^~~~~~~~
<source>:3:15: error: 'constexpr' constructor for union 'Optional<int>::<unnamed union>' must initialize exactly one non-static data member
Compiler returned: 1
Т.е. проблема в том, что компилятор не смог вывести constexpr конструктор для union-а. Проблема решается явным указанием инициализирующего значения по умолчанию:
union {
T value = {};
};
или
constexpr Optional() : value{}, has_value_{false} { }
Кстати, зачем здесь union?