Threads are a bad idea for the same reason manual handling of memory space is a bad idea. Languages should provide primitives that only allow for safe construction of expressions that are run concurrently by the runtime.
Then you run into issues like that post recently where you can't have different threads running in different context, because the runtime is the one deciding/controlling when new threads are spawned.
More seriously, in C++ apps (Games financial trading etc...) it is common enough to need to carefully manage memory to get that last bit of performance even after saturating all the CPUs and GPUs. Superficially your advice makes sense.
Going forward I think I might leave threads in the same mental bucket as allocators and see if that heuristic holds up.