Reputation: 4076
I have the following unordered_set:
class ArtifactImpl{...};
class ArtifactSetKeyOps
{
public:
std::size_t operator()(const ArtifactImpl& artifact) const noexcept;
bool operator()(const ArtifactImpl& lhs, const ArtifactImpl& rhs) const noexcept;
};
std::unordered_set<ArtifactImpl,
ArtifactSetKeyOps,ArtifactSetKeyOps> artifactSet_;
Note that my hash and predicate template argument/s have a noexcept specification.
I'm aware that find isn't marked noexcept, but in practice find should not perform allocations...
e.g:
const ArtifactImpl& foo() noexcept
{
auto pos = artifactSet_.find(key);
//etc...
}
Even though foo() here above goes against find's noexcept specifications, I'm wanting to know whether the specification holds practically iff one provides one's own noexcept hash and comparison.
Upvotes: 0
Views: 820
Reputation: 41096
tl;dr: noexcept
seems useful only for move constructor/assignment operator.
If you would dare to accept cplusplus.com or even me as sufficient authority: it does not throw any exception, unlessan aspect does - such as the allocator or a comparator throws, nothing throws.
(I should probably go dig out the relevant ISO passages now...)
However, as to my understanding, noexcept
isn't particulary useful here:
Andrzej has a detailed explanation on his blog, from which I (mis)quote the relevant parts here:
noexcept
doesn't buy much if the implementation throws despite the specificationfor certain functions, like
vector<T>::push_back
using move constructors/assignments ofT
instead of copy constructors/assignments can dramatically increase performance. However, if this move constructor/assignment can potentially throw,push_back
would loose the strong exception safety guarantee. In order to take an advantage of the move operations (where possible) and at the same time keep the strong guarantee, there needs to be a way to determine if a given move operation is potentially throwing or not, and use it or alternatively fall back to good old copying. This is exactly what functionstd::move_if_noexcept
does, but it needs T’s operations to be marked as noexcept where appropriate.
Upvotes: 1
Reputation: 4770
It could throw if you hash function (which it must call) throws. For that reason alone I wouldn't use it. But more importantly, I wouldn't use the noexcept
specifier because it goes against the find
function's specifications.
Upvotes: 1