Michbeckable
Michbeckable

Reputation: 1881

STL map insertion copy constructor

I have objects of type MyClass stored as pairs <std::string, MyClass> in an STL Map. The std::string is a unique name for each MyClass object. I want every MyClass object to be instantiated only ONCE per name and thus destroyed only once at the end in my application. So I try to avoid invocation of copy constructors or default constructors, as they might invoke destruction. A MyClass object refers to some kind of ressource that shall be allocated/freed only once. I tried to use this code to create instances of MyClass, put them in my map and give a pointer to the just created instance back.

MyClass* FooClass::GetItem(std::string name)
{
    MyClass* item = GetItemExists(name);

    if (item == NULL)
    {
        item = &(*((this->myMap.insert(std::pair<std::string, MyClass>
                                      (name, MyClass(name)))).first)).second;       
    }

    return item;
}

Creation and insertion works this way. But the destructor of Class MyClass is called 3! times. Even the return item; statement invokes the destructor, as this is a pointer?! I thought this is impossible and must be forced by delete item?!

I thought an alternative is to store pointers MyClass* instead of objects in the map. Or is there a better alternative? I did not use myMap[name] = MyClass(name); to avoid copy/destruction, but I think insert doesnt make it better.

Upvotes: 1

Views: 1400

Answers (1)

ecatmur
ecatmur

Reputation: 157334

You need to emplace and piecewise construct the inserted element:

item = &(this->myMap.emplace(std::piecewise_construct,
                             std::forward_as_tuple(name),
                             std::forward_as_tuple(name)).first->second);

Upvotes: 1

Related Questions