Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert an object pointer into a map of maps through emplace() does not work

I'm trying to insert a pointer object to a map through emplace() but it does not work.

I've created a simple representation of the problem below. I'm trying to insert to newFooList pointer object type Foo*.

I can't seem to find a way to create a type for FooMap* in std::map<int, FooMap*> m_fooMapList. Should it be done with the new on the second field of the map?

#include <iostream>
#include <utility>
#include <stdint.h>
#include <cstdlib>
#include <map>

class Foo
{
    private:
        int m_foobar;
    public:
        Foo(int value)
        {
            m_foobar = value;
        }
        void setfoobar(int value);
        int getfoobar();
};

class FooMap
{
    private:
        std::map<int, Foo*> m_newFoo;

    public:
        FooMap() = default;
};

class FooMapList
{
    private:
        std::map<int, FooMap*> m_fooMapList;
    public:
        FooMapList() = default;
        void insertFoo(Foo* newFooObj);
};

int Foo::getfoobar(void)
{
    return(m_foobar);
}

void FooMapList::insertFoo(Foo* newFooObj)
{
    if(m_fooMapList.empty())
    {
        std::cout << "m_fooMapList is empty" << std::endl ;
    }

    //m_fooMapList.emplace( newFooObj->getfoobar(), newFooObj  );
    // Need to find a way to insert newFooObj  to m_fooMapList
    m_fooMapList.second = new FooMap;
}

int main() {
    FooMapList newFooList;

    for (auto i=1; i<=5; i++)
    {
        Foo *newFoo = new Foo(i);
        newFoo->getfoobar();
        newFooList.insertFoo(newFoo);
    }

    return 0;
}

On g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28)

$  g++ -std=c++11 -Wall map_of_map.cpp 
map_of_map.cpp: In member function ‘void FooMapList::insertFoo(Foo*)’:
map_of_map.cpp:51:18: error: ‘class std::map<int, FooMap*>’ has no member named ‘second’
     m_fooMapList.second = new FooMap;
like image 987
Inian Avatar asked Dec 13 '22 12:12

Inian


1 Answers

m_fooMapList is defined as

    std::map<int, FooMap*> m_fooMapList;

So to insert into it, you need an int and a pointer to FooMap:

    m_fooMapList.emplace(newFooObj->getfoobar(), new FooMap);

Having said that, you should use C++ value semantics and rely less on raw pointers:

    std::map<int, FooMap> m_fooMapList; // no pointers

    m_fooMapList.emplace(newFooObj->getfoobar(), {}); // construct objects in-place

That is, instances of FooMap can reside directly in the map itself.

That way you get better performance and avoid memory leaks.

It's also worth looking into smart pointers (e.g. unique_ptr) if you really want to work with pointers.

like image 50
rustyx Avatar answered Dec 29 '22 00:12

rustyx