I think this is right on the money. There are a lot of things you can do with C++ (and other languages -- even C probably) that feel good at the time, only to learn later that they don't age well.
I've never seen it analyzed deeply why this is, but I suspect it has something do with how "fungible" the code is when you're done. Will your design let you make small design changes with relatively small and localized code changes, or has your complicated template/inheritance-based design "locked up" your code into a particular pattern, where changing any of the design assumptions requires "unwinding" a highly intertwined structure?
I don't know the rigorous answer to this question, so I design with various heuristics, which mostly boil down to some version of "this is getting a bit too complex or too highly leveraged." What I mean by "leveraged" is that some significant guarantee or invariant is achieved through a complicated contract between two different objects. I try to keep the design of every individual type/object as "flat" and unsubtle as possible; again vague terms, but I know it when I see it.