0

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?

w-m
  • 10,772
  • 1
  • 42
  • 49
  • Try commenting out the call to `push_back` and see if it compiles or not. – Spencer Nov 04 '19 at 20:59
  • Yes, the `push_back` is the issue. Without the `push_back`, it compiles. But I need to push the map into the vector. – w-m Nov 04 '19 at 21:00
  • You can replace `vector` by `list` to avoid reallocations inside `vector` when `push_back` is called which involves copies of map. Or use `unique_ptr` as elements of vector: `std::vector>>`. Your problem is related with `noexcept` you can read about it [here1](https://stackoverflow.com/questions/53168836/does-visual-studio-2017-need-an-explicit-move-constructor-declaration) or [here2](https://stackoverflow.com/questions/47604029/move-constructors-of-stl-containers-in-msvc-2017-are-not-marked-as-noexcept). – rafix07 Nov 04 '19 at 21:10
  • I removed `push_back` and replaced it with a call to `reserve(8)` and got the same error. It's in the instantiation of something in `map` involving the allocation of memory. – Spencer Nov 04 '19 at 21:19
  • https://godbolt.org/z/WStoDJ – Spencer Nov 04 '19 at 21:25
  • @rafix07 thanks! Would you want to make this an answer to the question? – w-m Nov 04 '19 at 21:37

0 Answers0