Does Visual Studio 2017 need an explicit move constructor declaration?

后端 未结 4 1296
南笙
南笙 2020-12-15 08:29

The below code can be compiled successfully using Visual Studio 2015, but it failed using Visual Studio 2017. Visual Studio 2017 reports:

error C2280:

4条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-15 08:58

    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.

提交回复
热议问题