Declaring defaulted assignment operator as constexpr: which compiler is right?

I think all three compilers are wrong.

[dcl.fct.def.default]/3 says:

An explicitly-defaulted function that is not defined as deleted may be declared constexpr or consteval only if it would have been implicitly declared as constexpr. If a function is explicitly defaulted on its first declaration, it is implicitly considered to be constexpr if the implicit declaration would be.

When is the copy assignment operator implicitly declared constexpr? [class.copy.assign]/10:

The implicitly-defined copy/move assignment operator is constexpr if

  • X is a literal type, and
  • […]

Where a literal type is, from [basic.types]/10:

A type is a literal type if it is:

  • […]
  • a possibly cv-qualified class type that has all of the following properties:

    • it has a trivial destructor,
    • […]

A1 doesn’t have a trivial destructor, so its implicit copy assignment operator isn’t constexpr. Hence that copy assignment operator is ill-formed (gcc and msvc bug to accept).

The other two are fine, and it’s a clang bug to reject A2.


Note the last bit of [dcl.fct.def.default] that I quoted. You don’t actually have to add constexpr if you’re explicitly defaulting. It would be implicitly constexpr where that is possible.

Leave a Comment