I'm dealing with an application, that needs to read in 10+ CSV-files (of different kind) as input. The data is read into a container -- std::map or vector.
Previously each kind had its own parsing function, and I'm working on unifying that into a single templatized function: to have save on future code-maintenance and provide uniform error-reporting for broken files.
This function reads each line, discerns, whether the container type has the concept of a key (like map) and uses emplace for those, and emplace_back for the others (like vector).
The only expectation from the value class of the container is that its constructor can instantiate from a CSV-line. Any exception by the constructor is a fatal error -- the input filename and line-number are reported, and the program exits:
try {
if constexpr (is_associative_container<Container>(NULL)) {
result->emplace(typename Container::key_type(
key, keylen), value);
} else {
result->emplace_back(value);
}
} catch (const std::exception &e) {
fprintf(stderr, "%s:%zd: %s\n", path, line, e.what());
goto failure;
}
This all works and I'm happy -- about 75% of the CSV-parsing is now done by this function.
I'm now facing the remaining quarter of the CSV-files, which are less straightforward: because certain rows in them require special treatment and their content isn't supposed to be stored in the container.
How can the value_type's constructor signal to the function, that the exception it is throwing should not considered fatal? One way is to pick one of the standard exceptions (std::bad_function_call?) as a signal, but that'd mean, the picked exception mustn't occur unexpectedly -- which is unreliable...
Anything else?
A question edit overlapped with writing this answer. The original answer is below.
Note that in your current code you already do make a distinction between exceptions inherited from
std::exceptionand those that do not inherit fromstd::exception. Good style is to inherit all exceptions fromstd::exceptionbut reality is usually different.You could introduce some special type of exception to be thrown:
Old answer about dynamic exception specifications...
As mentiond in comments, dynamic exception specifications are removed from C++17.
Before C++17 a function that did throw an exception not listed in the exception specification did the following (from cppreference):
There is no way out unless you know some exception that would be accepted from the exception specification, but in general you do not know that. I am not aware of deducing the "allowed" exceptions in generic code. Anyhow, the feature is removed. And in some sense it was already "fatal" to throw an exception not listed in the exception specification, its not something you have to do extra.