I'm writing a program containing many long for-loops, and I want to add a progress bar indicator to each. To do this, I wrote struct ProgressBar to accomplish this. The interface is as follows:
struct ProgressBar {
int start, end; // starting and ending values of the loop variable
const int &curr; // const reference to the loop variable
/* Update the progress bar by inspecting the current value of "curr" */
void update();
/* Constructor; the reference "curr" is initialized in the member initializer list, as it must be */
ProgressBar(int start, int end, const int &curr);
~ProgressBar() {
cout << "100% done" << endl;
}
};
And the idealized usage is
for (auto [i, pb] = pair{0, ProgressBar(0, 100, i)}; i <= 100; ++i) {
pb.update();
/* ... */
}
This does not work for at least two reasons:
ProgressBar(0, 100, i)causes a compiler error, since it depends on the loop variablei, whose type has not been deduced yet (error: use of ‘i’ before deduction of ‘auto’).ProgressBar(0, 100, i)needs to be evaluated afteri, but I believe thepairconstructor, like all C++ functions, does not guarantee any particular order of evaluation of parameters of functions.
Any design ideas for what I should do instead?
Why do you need two variables to count the loop? Can you not include the state as part of the
progress bar.Then you simply need a way of exposing the current state (either as some getter or simply check if it is done via boolean check) and a way of updating it. You could use
update()as that method (or add ++ to your class).