I have a timer class that I have written. Any single timer seems to work perfectly. I was trying to add a load of them to a vector and start a load of them, but because it has a thread member I needed to write a move/copy constructor. I decided to make it move only (non copy). So now I am able to add the timer to a vector (note link to full code at the bottom).
However I noticed some odd behaviour. Here is a how I am adding the timers to a vector (see NOTE 1 and 2):
int main()
{
// Due to godbolt's limited resources (I think) I could only add 3
constexpr size_t num = 3;
std::vector<timer> timers;
for (size_t i = 0; i < num; i++)
{
timer tmr;
timers.emplace_back(std::move(tmr));
// NOTE 1: this way does not work quite right
// timers[i].start(100, [i]{ std::cout << i << std::flush; }, false);
}
// NOTE 2: So I now start the timers in a second loop which seems to work
for (size_t i = 0; i < num; i++)
{
timers[i].start(100, [i]{ std::cout << i << std::flush; }, false);
}
// Let the timers run for a while
SLEEP_MSEC(1000);
std::cout << "\n============ end ==============" << std::endl;
return 0;
}
When I run this I get the following output (each timer should print its number, so 0,1 and 2):
move c'tor
~timer()
move c'tor
move c'tor
~timer()
~timer()
move c'tor
move c'tor
move c'tor
~timer()
~timer()
~timer()
210120210102021210120201102 <------- HERE all timers running
============ end ==============
~timer()
~timer()
~timer()
When I remove the second loop and re-enable starting the timer inside the first loop I get (each timer should print its number, but only 2 is printing):
move c'tor
~timer()
move c'tor
move c'tor
~timer()
~timer()
move c'tor
move c'tor
move c'tor
~timer()
~timer()
~timer()
222222222 <-------- HERE only the last timer seems to run
============ end ==============
~timer()
~timer()
~timer()
Here is the full code on godbolt setup for the non-working loop: https://godbolt.org/z/fFtjt2
Both seem to output the correct number of move/destructors and at the right times etc. But I can't spot the issue here. My guess is that I have done the move constructor wrong, but I can't see why.