I’m in a discussion at work as to how to properly handle containers as parameters.
We have a function that takes in a container parameter, and wants to return the container filled ONLY with what the function puts into it:
class bar;
void foo(std::vector<bar> &bars)
{
//do stuff that fills bars.
//exceptions may be thrown.
//we may also legally return early
return;
}
On one side of the discussion, we have people that say we should bars.clear() first and then run the function.
For example:
void foo(std::vector<bar> &bars)
{
bars.clear();
//do stuff that fills bars.
//exceptions may be thrown.
//we may also legally return early
return;
}
My own preference is to try to reach the strong exception guarantee as closely as I can, which means making a local container, filling that and swapping before returning, but otherwise leaving bars untouched.
For example:
void foo(std::vector<bar> &bars)
{
std::vector<bar> localBars;
//do stuff that fills localBars.
//exceptions may be thrown.
//we may also legally return early
if (returnEarly)
{
bars.swap(localBars);
return;
}
//do more stuff that may change localBars
bars.swap(localBars);
return;
}
The first example is the ‘classic’ method; of clearing your parameters before doing anything and going from there.
The second method, to me, sets up a strong exception guarantee (assuming nothing else the function does can change internal states), and avoids a clear() call.
Are there any advantages or disadvantages to picking one method over the other one?
Note that for this function, a strong exception guarantee isn’t required; if the function fails nothing in the parameters or anything else it does will matter by the time it gets up to the exception handler.
The two are really different.
Advantages of
clear:barsAdvantages of
swap:The question cannot be answered in general, what semantics/guarantees do you seek in your case ?