21

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:

  • Visual Studio's compiler implicitly deletes 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'
  • Clang defines the operator, but it does not permit using it in constant expressions:
note: pointer to temporary is not a constant expression
note: temporary created here
    9 | constexpr bool b = ( U{} == U{} );

Which implementation is correct here?

2
  • Why would you use this though? How is an empty union helpful? Commented Oct 18 at 19:16
  • @Daniel, empty union is very similar to empty struct, but it has some interesting properties like it cannot be a base class, which is something one wants to prevent sometimes. Commented Oct 18 at 20:06

1 Answer 1

24

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?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.