lundi 4 novembre 2019

vector of maps of non-copyable objects fails to compile in MSVC

The following code (also in https://godbolt.org/z/NSG6Qz) compiles fine in gcc, clang and Visual Studio 2013, but does not compile in recent MSVC versions:

#include <map>
#include <vector>

class MoveOnly {
 public:
  MoveOnly() {}
  MoveOnly(const MoveOnly&) = delete;
  MoveOnly& operator=(const MoveOnly&) = delete;
  MoveOnly(MoveOnly&&);
  MoveOnly& operator=(MoveOnly&&);
};

int main() {
    std::vector<std::map<int, MoveOnly>> vecOfMaps;
    std::map<int, MoveOnly> map;
    vecOfMaps.push_back(std::move(map));
}

The compilation in all MSVC versions in godbolt fails, in v19.22 with these errors (excerpt):

error C2280: 'std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)':
             attempting to reference a deleted function
[...]
note: while compiling class template member function
      'std::map<int,MoveOnly,std::less<int>,std::allocator<std::pair<const _Kty,_Ty>>>::map(
       const std::map<_Kty,_Ty,std::less<int>,std::allocator<std::pair<const _Kty,_Ty>>> &)'

MSVC does not have problems pushing non-copyable objects into a std::map. Pushing non-copyable objects into std::vector works as well. But pushing the map of non-copyable objects into the vector fails.

Why doesn't this compile?

Is there a workaround that can be applied to the MoveOnly class to make this code compile in MSVC, without losing the non-copyable attribute?

Aucun commentaire:

Enregistrer un commentaire