I've noticed that some standard functions having a wide contract such as functions in [iterator.range] conditionally do not throw exceptions, but they are not marked as conditionally noexcept.
EDIT: It is described in this paper:
Each library function having a wide contract, that the LWG agree cannot throw, should be marked as unconditionally noexcept.
If a library swap function, move-constructor, or move-assignment operator is conditionally-wide (i.e. can be proven to not throw by applying the noexcept operator) then it should be marked as conditionally noexcept. No other function should use a conditional noexcept specification.
But there are some functions that do not obey this guideline such as std::cbegin. And I did not find a reason in this paper.
Why?
Another case is that some functions should be non-throwing, but the standard doesn't say anything about it. Such as erase(q) (q denotes a valid dereferenceable constant iterator) of associative containers. This allows the implementation to throw any standard exception, according to [res.on.exception.handling#4]:
Functions defined in the C++ standard library that do not have a Throws: paragraph but do have a potentially-throwing exception specification may throw implementation-defined exceptions.170 Implementations should report errors by throwing exceptions of or derived from the standard exception classes ([bad.alloc], [support.exception], [std.exceptions]).
So if you want to swallow any implementation-defined exceptions they throw, you have to use a try-catch block.
std::set<int> s{1};
try
{
s.erase(s.cbegin());
}
catch (...) {}
It's ugly and inefficient, but necessary. So I also don't know of any benefit to this.