C++ allows us to make union class type without any data members. (cppreference even contain an example with it.)
Can one request the compiler to provide default implementation of equality comparison operator for such types? (It can be necessary for some generic code requiring comparison of objects.)
This program:
union U {
constexpr bool operator ==(const U&) const = default;
};
// error in MSVC
bool a = ( U{} == U{} );
// error in Clang
constexpr bool b = ( U{} == U{} );
makes the compilers diverge:
operator ==:error C2280: 'bool U::operator ==(const U &) const': attempting to reference a deleted function
note: see declaration of 'U::operator =='
note: 'bool U::operator ==(const U &) const': function was implicitly deleted because 'U' is a union-like class
error C2088: built-in operator '==' cannot be applied to an operand of type 'U'
note: pointer to temporary is not a constant expression
note: temporary created here
9 | constexpr bool b = ( U{} == U{} );
Which implementation is correct here?
The wording from [class.compare.default] reads:
A defaulted
<=>or==operator function for class C is defined as deleted if any non-static data member of C is of reference type or C has variant members ([class.union.anon]).
An empty union doesn't actually have variant members, so this restriction technically doesn't apply. So, I see no reason per the current wording why it shouldn't be valid — and once it's valid, it should certainly be usable as a constant expression. The relevant equality wording is defined in terms of subobjects, which there aren't any, so it should just be trivially true.
This is separate from the question of whether it should be valid. Probably not?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With