Put noexcept
on your move constructor:
TestClass(TestClass&& other) noexcept {
Elaboration: I was going to give this one Pierre, but unfortunately the cppreference source is only approximately correct.
In C++03
vector<T>::push_back(T)
has the "strong exception guarantee". That means that if the push_back
throws an exception, the vector is left in the same state it had prior to the call to push_back
.
This guarantee is problematic if the move constructor throws an exception.
When the vector
reallocates, it would like to move the elements from the old buffer to the new. However if any one of those moves throws an exception (besides the first), then it is left in a state where the old buffer has been modified, and the new buffer doesn't yet contain everything it is supposed to. The vector
can't restore the old buffer to its original state because it would have to move elements back to do so, those moves might also fail.
So a rule was laid down for C++11:
If T
has a noexcept
move constructor, that can be used to move the elements from the old buffer to the new.
Otherwise if T
has a copy constructor, that will be used instead.
Otherwise (if there is no accessible copy constructor), then the move constructor will be used after all, however in this case, the strong exception safety guarantee is no longer given.
Clarification: "copy constructor" in rule 2 means a constructor taking a const T&
, not one of those weenie so-called T&
copy constructors. :-)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…