0

I have a class that looks like this

class MyCalss
{
public:
    std::unordered_map<std::string, std::unique_ptr<Entity>> getMyMap() const;

private:
    std::unordered_map<std::string, std::unique_ptr<Entity>> m_myMap;
}

In the implementation, I simple return m_myMap in getMyMap() like so,

std::unordered_map<std::string, std::unique_ptr<Entity>> MyClass::getMyMap() const
{
    return m_myMap;
}

How come this is not allowed? I get a bunch of compilation error doing this.

Zhen Liu
  • 7,550
  • 14
  • 53
  • 96
  • is there a reason you want to use unique_ptr there instead of the "Entity"? i cannot imagine one. – mikk Nov 14 '22 at 08:49
  • 4
    Read the lines of the compilation errors you didn't bother posting... *closely*. It will tell you the copy ctor of the map template expansion you're using has been deleted. Considering the map contains un-copyable values, that shouldn't come as a surprise. – WhozCraig Nov 14 '22 at 08:49
  • Linked answer is for `std::vector`, but the same thing happens with any standard container. – MSalters Nov 14 '22 at 08:55
  • @mikk Polymorphism? – Daniel Langr Nov 14 '22 at 09:14

2 Answers2

1

Your getter is trying to return a copy of m_myMap, but the copy constructor of std::unique_ptr<Entity> is deleted: it means that a std::unique_ptr cannot be copied by definition, being unique.

Probably you should return a const reference to m_myMap instead of a copy, declaring your getter as:

const std::unordered_map<std::string, std::unique_ptr<Entity>>& getMyMap() const;
Giovanni Cerretani
  • 1,693
  • 1
  • 16
  • 30
0

Because a std::unique_ptr cannot be copied.

std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the std::unique_ptr goes out of scope.

Since you return a copy of m_myMap, the copy constructor of std::unordered_map constructs a container with a copy of its contents, and fails to do so since std::unique_ptr cannot be copied.

mfnx
  • 2,894
  • 1
  • 12
  • 28
  • 1
    This answer would be better if it pointed out that this property is usually transitive. A standard container of `unique_ptr`s is also not copyable. – MSalters Nov 14 '22 at 08:53
  • 2
    @Jamit that's actually purpose of scoped_ptr which didn't make it into standard. Unique_ptr ensures that object would be disposed and neither copied nor left dangling pointers – Swift - Friday Pie Nov 14 '22 at 09:05