It really depends. As a rule of thumb, limit the number of threads to something close to the number of cores (otherwise you might have too much context switchs). You might use std::thread::hardware_concurrency()
as a hint. Often, you organize your program with a thread pool.
However, what really matters is the number of active threads. Some programs have hundreds of threads but are organized so that only a few of them are active (i.e. runnable) at any given instant, and most of them being idle (waiting for IO, or for some mutex or condition variable).
Be aware that a thread is a quite heavy resource (in particular because it has its own call stack, usually at least a megabyte). So don't have too many of them (hence, having thousands of threads is generally unreasonable, unless you have a very powerful and expansive computer).
The Intel hyper-threading technology is often disappointing. You probably don't want to have 8 active threads on an Intel processor with 4 cores and 8 hyperthreads. You need to benchmark, but you should expect some bad performance in such case (perhaps having 4 or 6 active threads would make your overall performance better).
Threads are an abstraction provided and managed by the operating system. So read Operating Systems: Three Easy Pieces to understand more about OSes.