Is is good practice to declare a function as noexcept even if it calls a function that can throw |
The answer is that it depends on the function.
I'll talk about the Committee's general policy for the standard library:
Were you proposing
doSomething for use in the standard library, then you would submit a potentially-throwing function
unless your function is specified as having a wide contract and isn't specified to throw.
WG21's internal guidelines suggest that functions with a narrow contract should generally not be marked
noexcept. Briefly, the rationale is that marking such functions non-throwing precludes testing for its invariants in a systematic way.
A function
may acquire a narrow contract as a result of being marked
noexcept. For example, the function
f has a wide contract:
1 2 3
|
// N.B.: std::istream::operator>>() is specified to throw
// depending on the stream's exception mask
void f(int &x) { std::cin >> x; }
| |
But the function
g (identical to
f, but
noexcept) has a narrow contract, and should be potentially-throwing:
|
void g(int &x) noexcept { std::cin >> x; }
| |
The policy is at
https://wg21.link/p0884r0 , but another paper contains its rationale:
https://wg21.link/n3248
I'm not
necessarily suggesting that you follow that policy. However, it does explain why many functions in the standard library are potentially-throwing despite not being specified to throw exceptions, and why the library does not supply conditionally-
noexcept functions where we might otherwise expect.