9

I have a STL map in C++ where the key is an unsigned int, and the value is a class whose constructor is:

Foo::Foo(unsigned int integerValue){
    //Some stuff
}

At other class I have declarated the std::map at the header:

private:
    std::map<unsigned int, Foo> *m_mapFoo;

And at the cpp file I created it and inserted instances of Foo:

m_mapFoo = new std::map<unsigned int, Foo>;
m_mapFoo->insert(0, new Foo(0));
m_mapFoo->insert(1, new Foo(1));

But I'm getting the following error at the insert methods:

no matching function for call to ‘std::map<unsigned int, Foo, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, Foo> > >::insert(const unsigned int&, Foo*)’

Similar problem at find method:

m_mapFoo.find(0)->second->someFunctionIntoFooClass();

Where the error is exactly the following:

request for member ‘find’ in ‘((Foo*)this)->Foo::m_mapGeoDataProcess’, which is of non-class type ‘std::map<unsigned int, Foo, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, Foo> > >*’

Additional notes: I don't have a Foo copy constructor, but I don't think that's the problem.

Any help understanding this errors?

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
Roman Rdgz
  • 12,836
  • 41
  • 131
  • 207
  • How do you expect to copy into a map if you don't have a copy constructor? – Pubby Nov 20 '12 at 14:54
  • I have read around stackoverflow and some people say you must have, some say you don't need. But I don't know if that's applicable only to [] insertation and not insert method. See http://stackoverflow.com/questions/1478330/c-stl-map-with-a-custom-class-as-second-type – Roman Rdgz Nov 20 '12 at 14:59
  • You need the copy constructor for `insert`. `emplace` doesn't need it, though. – Pubby Nov 20 '12 at 15:03
  • 1
    @Pubby OP probably has the compiler synthesized copy constructor. – juanchopanza Nov 20 '12 at 15:06

3 Answers3

6

You have a pointer to a map containing Foo values

std::map<unsigned int, Foo> *m_mapFoo;

and you are treating it as if it contained Foo pointer values:

std::map<unsigned int, Foo*> *m_mapFoo;

Try this:

m_mapFoo = new std::map<unsigned int, Foo>;
m_mapFoo->insert(std::make_pair(0, Foo(0)));
m_mapFoo->insert(std::make_pair(1, Foo(1)));

As for the second error, you have a pointer to a map, so you need

std::map<unsigned int, Foo>::iterator it = m_mapFoo->find(0);
if (it) {
  it->second.someFunctionIntoFooClass();
} else {
  // entry not found
}
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
3

Your map is typed to store objects of type Foo, not pointers to objects of type Foo. Seeing as you're trying to initialise the elements with new and access their members via ->, you probably want:

private:
    std::map<unsigned int, Foo*> *m_mapFoo;
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
0

From the little information you give, it seems unlikely that you need to use pointers anywhere: Try this:

In the header:

private:
    std::map<unsigned int, Foo> m_mapFoo;

And at the cpp file:

m_mapFoo[0] = Foo(0);
m_mapFoo[1] = Foo(1);

The semantics of operator[] are slightly different than .insert(). If you need .insert(), use it. But unless you are relying upon the subtle difference, use the more readable operator[].

Similarly at the find method, the expression becomes much more readable if you avoid pointers and use operator[]:

m_mapFoo[0].someFunctionIntoFooClass();
Robᵩ
  • 163,533
  • 20
  • 239
  • 308