https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120088
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Last reconfirmed| |2025-05-06
Ever confirmed|0 |1
Keywords| |rejects-valid
Status|UNCONFIRMED |NEW
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The libstdc++ implementation can be reduced to the following, which is rejected
the same way:
#include <memory>
struct unexpected { };
template<typename T, typename E>
struct expected
{
constexpr expected(unexpected) noexcept : m_unex(), m_has_value(false) { }
constexpr expected() noexcept : m_void(), m_has_value(true) { }
expected(const expected&) = default;
constexpr ~expected() = default;
expected& operator=(const expected&) = delete;
constexpr expected&
operator=(const expected& x)
requires true
{
if (x.m_has_value)
emplace();
else
m_assign_unex(x.m_unex);
return *this;
}
constexpr void emplace()
{
if (!m_has_value)
{
std::destroy_at(&m_unex);
m_has_value = true;
}
}
constexpr void
m_assign_unex(const E& v)
{
if (m_has_value)
{
std::construct_at(&m_unex, v);
m_has_value = false;
}
else
m_unex = v;
}
union {
struct { } m_void;
E m_unex;
};
bool m_has_value;
};
constexpr bool quux() {
expected<void, int> foo1{unexpected{}};
expected<void, int> foo2{};
foo1 = foo2;
[[maybe_unused]] expected<void, int> foo3{foo1};
return true;
}
static_assert(quux());
I'm not sure what needs to be changed here.