I have a function that operates on a big chunk of data passed in as a sink argument. My BigData
type is already C++11-aware and comes with fully functional move constructor and move assignment implementations, so I can get away without having to copy the damn thing:
Result processBigData(BigData);
[...]
BigData b = retrieveData();
Result r = processBigData(std::move(b));
This all works perfectly fine. However, my processing function may fail occasionally at runtime resulting in an exception. This is not really a problem, since I can just fix stuff and retry:
BigData b = retrieveData();
Result r;
try {
r = processBigData(std::move(b));
} catch(std::runtime_error&) {
r = fixEnvironmnentAndTryAgain(b);
// wait, something isn't right here...
}
Of course, this won't work.
Since I moved my data into the processing function, by the time I arrive in the exception handler, b
will not be usable anymore.
This threatens to drastically reduce my enthusiasm for passing sink arguments by-value.
So here is the question: How to deal with a situation like this in modern C++ code? How to retrieve access to data that was previously moved into a function that failed to execute?
You may change the implementation and interfaces for both BigData
and processBigData
as you please. The final solution however should try to minimize drawbacks over the original code regarding efficiency and usability.