As of N3797 the C++ standard requires swap functions of containers to not throw any exceptions unless specified otherwise [container.requirements.general] (23.2.1§10).
swap member functions that are specified to not throw not declared noexcept?The same question applies to the specialized non-member swap overloads.
Further to what refp said, here's a post from Daniel Krügler on the std-discussion mailing list:
The internal policy to declare a function as unconditional noexcept is explained in
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3279.pdf
With the terminology used in that paper, std::vector's swap function has a narrowing contract, that is it has preconditions in regard to the allocators of the participating objects. This means, there exists the possibility that callers may violate the preconditions and an implementation should be allowed to signal this my different means than by termination. Therefore such functions should not be noexcept, but it should have an effective element "Throws: Nothing" because this applies to the situation when the preconditions are satisfied.
(link)
Said internal policy is the canonical, official answer to your question.
It may sound odd at first, but not explicitly stating that swap of standard container is noexcept is intentional; and it all boils down to undefined behavior (UB).
23.2.1p9General Container Requirements[container.requirements.general]The expression
a.swap(b), for containersaandbof a standard container type other thanarray, shall exchange the values ofaandbwithout invoking any move, copy, or swap operations on the individual container elements.Any
Compare,Pred, orHashobjects beloning toaandbshall be swappable and shall be exchanged by unqualified calls to non-memberswap.If
allocator_traits<allocator_type>::propagate_on_container_swap::valueistrue, then the allocators ofaandbshall also be exchanged using an unqalified call to non-memberswap. Otherwise, they shall not be swapped, and the behavior is undefined unless `a.get_allocator () == b.get_allocator ().
Note: italics added by me.
Why is the previous section relevant to my question?
Since the swap of standard containers has a precondition (most importantly the last paragraph of the previously quoted section of the Standard), that may lead to UB if not satisfied, the Standard doesn't want to impose "impossible" constraints on implementations.
The Standard says the following about undefined behaviour:
1.3.24undefined behavior[defns.undefined]Behavior for which this International Standard imposes no requirements.
Only criminals, and perhaps salesmen, would consider a No to be something other than a No, but when the Standard says "no requirements" it really means "no requirements"; marking the relevant swap functions as noexcept would impose a requirement on implementations, where there should be none.
Why doesn't the Standard want to impose such requirements?
There's an interesting paper (N3248) on this matter by Alisdair Meredith and John Lakos titled "noexcept prevents Library Validation".
In short it talks about how noexcept will prevent library implementation to use asserts in library code (ie. implementations of the standard library), even during debug mode, and the implications of that.
If C++ had a standardized "testing" vs "production" mode (as the paper calls it), where noexcept would conditionally apply, this would be far less problematic.. but as it currently stands; C++ has no "modes".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With