> At least in my domain I feel the problem is developers just throwing code at a problem until it compiles and exhibits the expected behavior in the happy path

I specialize in joining projects with "issues", specifically to help them deliver, improve reliability, performance, etc.

I have observed most projects with problems exhibit one of two "failure modes". I mean projects and not developers because projects tend to hire like developers and then developers mostly share same problematic quality. In the end it is not individual contributors who are at fault but management who allowed it to happen.

#1. Insufficient programming skills. This where developers don't use libraries because they don't even know they exist, can't recognize the problem they are solving as generic. This is where they can't structure the code because they haven't seen much code at all and/or are not interested in learning.

You can recognize this immediately as codebases with a lot of code duplication and very weak structure/abstractions.

#2. Too much programming ambition. This is where developers think so highly of themselves that they can't accept existing off the shelf components and will reinvent them because they can do better. They will write new everything because it will offer 10% performance increase in their specific case or just for the intelectual fun of doing it. They will obsess over ensuring there is no duplication of code at the cost of creating baroque structures that have no meaning and purpose other than ensure that every single component works in every single case supported by the application and in any possible future.

You can recognize this as codebases with no duplication but when you try to read the code it seems the structure is so complicated you need to have a huge map on entire wall and a guide to be able to travel the codebase. Most of the objects don't have any meaning in the domain of the problem and are just abstract "stuff" necessary to glue everything together.

I very much prefer working with case #1

The reason is that, as dumb as the code is, you can read it and understand what the author probably had in mind, what the application attempts to do. You can then work with the code, refactor functionality out, and so on.

In my experience case #2 is usually beyond repair (or at least beyond my abilities to repair). These developers become easily hostile -- because they think very highly of themselves they treat everybody as inferior and now I am trying to write some dumb unsophisticated code and so I must be dumb. They also tend to change jobs pretty easily so the only result of trying to fix that kind of project is people suddenly leaving it and management getting restless at the lack of progress.

And for some reason every single C++ team I worked with falls under case #2.

I think because, given so many options, you need to have ambition to willingly choose C++ as your main programming language and so the population is preselected.

Don't get me wrong, these are all highly intelligent people. But you can be very intelligent and still make a mess. I know because I was doing the same until I have acquired some wisdom based on my own mistakes and mistakes I have observed.