It is also important to separate C++ the language from its standard library.
As C++ the language has modernized, it has dramatically reduced the lines of code to express a given thing. And the more modern way of expressing the thing has stronger type safety, more flexibility, and better composability. Things that used to require a lot of template metaprogramming magic to pull off are now clean one-liners. Particularly in C++20, which is probably the biggest step-change since C++11, metaprogramming is simultaneously much more powerful and much more readable. A lot of code that used to be written is now metaprogrammed. Previous use cases that required C macros largely have native C++ equivalents at this point.
The major issue that makes C++ seem complex is the standard library, which was largely designed and written for legacy versions of C++. If you use the standard library heavily, it tends to want to be used in the style of C++ for which it was originally written. If you built a standard library for C++20 from first principles, it would look quite different from the one we have. Hence the proliferation of non-standard "standard" libraries for C++.