Another big one is implicit casting of void ptrs. I cast void pointers to specific types A LOT. There are many situations where you have to cast void pointers (that come from an abstract API that only deals with untyped memory) to specific types (higher-level application code), and I can't really be sure, but I think there isn't a nice way to do that in C++.
It might be because C++ wants you to use their elaborate abstractions and templates, which in many situations is just fluff that makes programs harder to read and maintain.
C++ also supports C-style casts but it's a code smell.
that's a pretty harsh take on it - how would you design it considering that initialization order has to be respected (else a lot of use cases would break; it's definitely not uncommon to have a member of a struct to depend on a previous member being initialized) ?
I have yet to find a particularly blocking use of the feature when test-driving it - it's on the other hand a great boon for readability (and definitely puts a nail in the coffin of named function parameters proposals imho).
Clang has demonstrated long before C++20 that it is possible to use the full C99 designated-init feature set in C++, so I really don't understand why the C++ Committee had to cut down the feature when there was already a fully working implementation.
PS: as an example for where C++20 designated initialization breaks down, see for instance [1], I tried to replicate this code in C++20, but quickly gave up (with the main problem being that it is impossible to remember the correct declaration order in big "option bag" structs like this.
[1] https://github.com/floooh/sokol-samples/blob/e0a93a21b17a663...