The below code can be compiled successfully using Visual Studio 2015, but it failed using Visual Studio 2017. Visual Studio 2017 reports:
error C2280:
Visual Studio 2017:
As @Evg indicated, the Visual Studio 2017's vector sourcecode finally call into _Uninitialized_copy because the implicitly-declared move constructor of Node is considered as not-nothrow (is_nothrow_move_constructible
is false) and is_copy_constructible
is true in Visual Studio 2017.
1) About is_nothrow_move_constructible
:
https://en.cppreference.com/w/cpp/language/move_constructor says:
The implicitly-declared (or defaulted on its first declaration) move constructor has an exception specification as described in dynamic exception specification (until C++17)exception specification (since C++17)
Maybe it's reasonable to consider is_nothrow_move_constructible
as false beacause Node
's data member std::unordered_map
's move constructor is not marked as noexcept.
2) About is_copy_constructible
:
As @Oliv says, it's seemingly not logical to compute is_copy_constructible
as true, specially considering the fact that Node
is not copy_constructible has been detected and reported as compile error by Visual Studio 2017 compiler. Node
is not copy_constructible beacause std::unique_ptr
is not copy_constructible.
Visual Studio 2015:
Visual Studio 2015's vector has a different implemetation. vec.push_back
->_Reserve
->_Reallocate
->_Umove
->_Uninitialized_move_al_unchecked
->_Uninitialized_move_al_unchecked1
->std::move(node)
. is_nothrow_move_constructible
and is_copy_constructible
are not involved. It just call std::move(node)
instead of copy constructor. So the sample code can be compiled successfully using Visual Studio 2015.