But it's also been the security nightmare of the century. And been used to build the most horrible messy codebases in existence.
C++ encourages coding style that leads to very complicated execution flow. Multiple inheritance. What's the actual concrete method this thing is going to call? Fire up the debugger and set a breakpoint...
Operator overloading. Yes, there are good uses for it. Like math code. Or some container implementations. Unfortunately it's often just hiding what's really going on or worse, bugs. Yeah, you're so clever overloading /-operator for building file paths...
Exceptions - there to provide untold number of possible execution paths making a typical C++ program flow nearly impossible to comprehensively understand. Exceptions seem to discourage from actually handling the errors as opposed doing something about it at the call site. There's often little you can do five nested calls above, where the exception is caught. Handling means almost always a some sort of logging function or user notification, not actually doing something about it. It's easy to forget it's not only about resource management. Side effects matter too! RAII doesn't undo IO.
Those features hide bugs and make C++ maintenance a true challenge.
Of course one can earn a steady income writing C++...