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

  • A+

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; 


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.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: