I just found out that the two swap functions for basic_string (member function and function in namespace std) are not declared with noexcept - neither in the standard library of GCC-4.8 nor in the most recent C++ draft N3690.
On the other hand, the move constructor as well as the move assignment operator are declared with noexcept. That shows that is should be possible to provide noexcept swap functions.
Question: What's the reason for not having the swap functions declared with noexcept?
Update: The problem is that I want to use a template function within my own swap functions, that uses static_assert to check that the swap is actually noexcept, e.g.:
struct foo {
bar_t bar;
baz_t baz;
void swap(foo& rhs) noexcept {
swap_noexcept(bar, rhs.bar);
swap_noexcept(baz, rhs.baz);
}
};
However, that works only if the swap functions are declared with noexcept, and that's not the case for basic_string
.
Paragraph 21.4.6.8 of the C++11 Standard specifies:
21.4.6.8
basic_string::swap
[string::swap]void swap(basic_string& s);
1 Postcondition: *this contains the same sequence of characters that was in s, s contains the same sequence of characters that was in *this.
2 Throws: Nothing.
3 Complexity: constant time.
Therefore, one must conclude the absence of noexcept
is an oversight.
Another clue is given by paragraph 21.4.6.3 on the assign()
member function:
basic_string& assign(basic_string&& str) noexcept;
Effects: The function replaces the string controlled by
*this
with a string of lengthstr.size()
whose elements are a copy of the string controlled bystr
. [ Note: A valid implementation isswap(str)
. — end note ]3 Returns:
*this.
If swap(str)
is supposed to be a valid implementation for assign()
, and assign()
is marked as unconditionally noexcept
, then it makes sense to assume swap()
to be noexcept
as well.
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