IMPORTANT UPDATE
Note: since this question is specifically about timers, its important to note there is a bug in gcc that if you are using std::condition
While your code will "work", it is sub-optimal for the intended purpose as timer.
There exists std::this_thread::sleep_until
which, depending on the implementation, possibly only just calls sleep_for
after doing some math anyway, but which might use a proper timer, which is vastly superior in terms of precision and reliability.
Generally, sleeping is not the best, most reliable, and most accurate thing to do, but sometimes, if just waiting for some approximate time is what's intended, it can be "good enough".
In any case, repeatedly sleeping for small amounts as in your example is a bad idea. This will burn a lot of CPU on needlessly rescheduling and waking threads, and on some systems (Windows in particular, though Windows 10 isn't so bad in that respect any more) it may add a considerable amount of jitter and uncertainity. Note that different Windows versions round to the scheduler's granularity differently, so in addition to generally being not overly precise, you do not even have consistent behavior. Rounding is pretty much "who cares" for a single large wait, but it is a serious problem for a series of small waits.
Unless the ability to abort the timer prematurely is a necessity (but in that case, there are better ways of implementing that, too!), you should sleep exactly once, never more, for the full duration. For correctness you should then check that you indeed got the time you expected because some systems (POSIX, notably) may under-sleep.
Over-sleeping is a different problem if you need it right, because even if you check and detect that case correctly, once it has happened there's nothing you can do about it (time has already passed, and never comes back). But alas, that's just a fundamental weakness of sleeping, not much you can do. Luckily, most people can shrug this problem off, most of the time.