C++20 added `[[no_unique_address]]`, which lets a `std::is_empty` field alias another field, so long as there is only 1 field of that `is_empty` type.
https://godbolt.org/z/soczz4c76
That is, example 0 shows 8 bytes, for an `int` plus an empty field.
Example 1 shows two empty fields with the `int`, but only 4 bytes thanks to `[[no_unique_address]]`.
Example 2 unfortunately is back up to 8 bytes because we have two empty fields of the same type...
`[[no_unique_address]]` is far from perfect, and inherited the same limitations that inheriting from an empty base class had (which was the trick you had to use prior to C++20).
The "no more than 1 of the same type" limitation actually forced me to keep using CRTP instead of making use of "deducing this" after adopting c++23: a `static_assert` on object size failed, because an object grew larger once an inherited instance, plus an instance inherited by a field, no longer had different template types.
So, I agree that it is annoying and seems totally unnecessary, and has wasted my time; a heavy cost for a "feature" (empty objects having addresses) I have never wanted.
But, I still make a lot of use of empty objects in C++ without increasing the size of any of my non-empty objects.
C++20 concepts are nice for writing generic code, but (from what I have seen, not experienced) Rust traits look nice, too.