1

I'm wondering why do I have this error compiling the following example code:

#include <unordered_map>
#include <memory>

class OneClass
{

};

using TestUnorderedMap = std::unordered_map<int, std::unique_ptr<OneClass>>;

class TestClass
{
public:
    TestUnorderedMap& getMap() { return m_map; }
private:
    TestUnorderedMap m_map;
};

void simpleTestFunction()
{
    TestClass t;
    TestUnorderedMap map = t.getMap();
}

I'm getting this error when compiling with Visual Studio 2022, can I not return a reference to an unordered_map that uses an std::unique_ptr as an object ?

D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\xutility(241): error C2280: 'std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>>::pair(const std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>> &)': attempting to reference a deleted function
  D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\utility(253): note: see declaration of 'std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>>::pair'
  D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\utility(253): note: 'std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>>::pair(const std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>> &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::unique_ptr<OneClass,std::default_delete<OneClass>>::unique_ptr(const std::unique_ptr<OneClass,std::default_delete<OneClass>> &)'
  D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\memory(3288): note: 'std::unique_ptr<OneClass,std::default_delete<OneClass>>::unique_ptr(const std::unique_ptr<OneClass,std::default_delete<OneClass>> &)': function was explicitly deleted
  D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\xutility(241): note: the template instantiation context (the oldest one first) is
  D:\Users\Rui Barreiros\Documents\Projectos\Audio\rSensors\rSensorServer_V2\test.cpp(20): note: see reference to class template instantiation 'std::unordered_map<int,std::unique_ptr<OneClass,std::default_delete<OneClass>>,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>>>>' being compiled
  D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\unordered_map(110): note: while compiling class template member function 'std::unordered_map<int,std::unique_ptr<OneClass,std::default_delete<OneClass>>,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>>>>::unordered_map(const std::unordered_map<int,std::unique_ptr<OneClass,std::default_delete<OneClass>>,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>>>> &)'
  D:\Users\Rui Barreiros\Documents\Projectos\Audio\rSensors\rSensorServer_V2\test.cpp(27): note: see the first reference to 'std::unordered_map<int,std::unique_ptr<OneClass,std::default_delete<OneClass>>,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>>>>::unordered_map' in 'simpleTestFunction'
  D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\unordered_map(111): note: see reference to function template instantiation 'std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>::_Hash<std::allocator<std::_List_node<std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>>,std::_Default_allocator_traits<_Alloc>::void_pointer>>>(const std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>> &,const _Any_alloc &)' being compiled
          with
          [
              _Kty=int,
              _Ty=std::unique_ptr<OneClass,std::default_delete<OneClass>>,
              _Hasher=std::hash<int>,
              _Keyeq=std::equal_to<int>,
              _Alloc=std::allocator<std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>>>,
              _Any_alloc=std::allocator<std::_List_node<std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>>,std::_Default_allocator_traits<std::allocator<std::pair<const int,std::unique_ptr<OneClass,std::default_delete<OneClass>>>>>::void_pointer>>
          ]
  ...snip...
7
  • 3
    You can return a reference to unique_ptr. You cannot create a copy out of that reference, and that's what simpleTestFunction tries to do. Did you mean TestUnorderedMap& map = t.getMap(); instead? Commented May 10, 2024 at 14:53
  • 7
    unique_ptr is not copyable and TestUnorderedMap map = t.getMap(); causes a copy Commented May 10, 2024 at 14:53
  • I'm confused.... what is the diference between 'TestUnorderedMap& map = t.getMap();' and 'TestUnorderedMap map = t.getMap();' shouldn't it be the same ? I also tried 'auto map = t.getMap();' and the error remains. Commented May 10, 2024 at 15:07
  • 1
    TestUnorderedMap& map = t.getMap(); is a good option to use. Commented May 10, 2024 at 15:10
  • 1
    No, it shouldn't be, and isn't the same. TestUnorderedMap& map = t.getMap(); defines map as a reference, which is initialized from the returned reference. TestUnorderedMap map = t.getMap(); defines map as a standalone unordered_map in its own right that is to be initialized as a copy of the one referenced by the returned reference, only the copy can't be made. Commented May 10, 2024 at 15:29

1 Answer 1

2

Figured out what was happening, thanks to @Yksisarvinen and @NathanOliver, I was creating a copy of the unordered_map object by using:

TestUnorderedMap map = t.getMap();

It should be using this instead:

TestUnorderedMap& map = t.getMap();

By using the first one, it would create a copy of the object into a new memory location, which unique_ptr does not allow. The second is just a reference.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.