A vector when it does a resize will attempt to use move semantics to move the objects from the old array to the new one. But if the templated object in the vector does not support a no throw noexcept
move constructor then it will revert to using copy construction so that the strong exception guarantee
is preserved.
But when I try this:
#include <vector>
class X
{
public:
// Needs default constructor
X() {}
// Copy operations disabled.
X(X const&) = delete;
X& operator=(X const&) = delete;
X(X&&) // throwable move constructor
{}
X& operator=(X&&) // throwable move assignment.
{return *this;}
};
int main()
{
// Vector of Size zero
std::vector<X> data;
// Vector of Size ten.
// Since the move constructor can potentially throw
// We have to copy elements when we do a resize
//
// But X has a disabled copy semantics
// Thus I would expect a compile time error here.
data.resize(10);
}
This compiles without error or warning:
> g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix
> g++ -std=c++11 test.cpp
>
The strong exception safety guarantee is not provided for noncopyable elements that have a throwing move constructor.
[vector.capacity]/p12-14 (emphasis mine):
void resize(size_type sz);
12 Effects: If
sz <= size()
, equivalent to callingpop_back()
size() - sz
times. Ifsize() < sz
, appendssz - size()
default-inserted elements to the sequence.13 Requires:
T
shall beMoveInsertable
andDefaultInsertable
into*this
.14 Remarks: If an exception is thrown other than by the move constructor of a non-
CopyInsertable
T
there are no effects.
Note that this doesn't require T
to be CopyInsertable
.
Internally, the implementation likely uses std::move_if_noexcept
, which, despite the name, is really "move if noexcept or if noncopyable".
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