Consider the following code (see it on Compiler Explorer):
#include <map>
#include <memory>
#include <vector>
#include <string>
int main()
{
std::vector<std::map<std::string, std::unique_ptr<int>>> test;
test.resize(2);
}
It's successfully compiled by GCC 9 and Clang 10, but MSVC 19.24 fails with the following errors:
C:/data/msvc/14.24.28314/include\xmemory(671): error C2280: 'std::pair<const std::string,std::unique_ptr<int,std::default_delete<int>>>::pair(const std::pair<const std::string,std::unique_ptr<int,std::default_delete<int>>> &)': attempting to reference a deleted function
C:/data/msvc/14.24.28314/include\utility(168): note: see declaration of 'std::pair<const std::string,std::unique_ptr<int,std::default_delete<int>>>::pair'
C:/data/msvc/14.24.28314/include\utility(168): note: 'std::pair<const std::string,std::unique_ptr<int,std::default_delete<int>>>::pair(const std::pair<const std::string,std::unique_ptr<int,std::default_delete<int>>> &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::unique_ptr<int,std::default_delete<int>>::unique_ptr(const std::unique_ptr<int,std::default_delete<int>> &)'
C:/data/msvc/14.24.28314/include\memory(1912): note: 'std::unique_ptr<int,std::default_delete<int>>::unique_ptr(const std::unique_ptr<int,std::default_delete<int>> &)': function was explicitly deleted
C:/data/msvc/14.24.28314/include\xtree(358): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,_Ty&>(_Alloc &,_Objty *const ,_Ty &)' being compiled
As I understand the error message, for some reason std::pair<const std::string,std::unique_ptr<int>>
needs to be copied. I suppose it's because std::map
has to be copied in case of a reallocation.
But why? Doesn't std::map
have a move constructor? Is it a bug in MSVC? Or are both GCC and Clang wrong?