Problem with std::map

This topic is 3552 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hello, I am using std::map to manage textures, and I have a function that returns the texture id in GLuint form, but when I try to return the texture the compiler gives me a funky error. Here is the specific function:
GLuint TextureManager::GetImage(const std::string &name) const
{
return TextureImages[name];
}
The error is: texture.cpp:77: error: passing const std::map<std::string, GLuint, std::less<std::string>, std::allocator<std::pair<const std::string, GLuint> > >' as this' argument of _Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = std::string, _Tp = GLuint, _Compare = std::less<std::string>, _Alloc = std::allocator<std::pair<const std::string, GLuint> >]' discards qualifiers Can someone tell me what is wrong?

Share on other sites
The [] operator of std::map is not a const accessor; see footnote 3 here for why. Use std::map::find instead.

Share on other sites
The index operator from std::map can modify the content if there isn't the string that goes to your function.

Use the find method and return the value that is in the returned iterator.

Edit: Ahh beaten by Sneftel

Share on other sites
TextureManager::GetImage() is a const member function, however the function operator[] is not a const member function of std::map. The reason it isn't const is because operator[] returns a reference to the element you're accessing. Additionally, what is problematic about that operator is that if an element with the specified key is not found, one is added to the map.

To fix this use member function find() on the map instead.

Share on other sites
Oh oh, right right. Silly me. Thank you, sneftel. =)

Share on other sites
Okay so I have a map that is <filenames, GLuints> and I want to pass this into glGenTextures, how do I do that? There's gotta be a way like you do with std::vector right?

In otherwords I want to take the ->second of the map make it look like an array and pass it into glGenTextures.

Share on other sites
There's no way to make it "look like" an array, because it isn't an array. Iterate through the entries in the map, passing the value of each one to glGenTextures in turn.

Share on other sites
Quote:
 Original post by NiddlesIn otherwords I want to take the ->second of the map make it look like an array and pass it into glGenTextures.

You cant do this.

You can do it with vector because the internal representation of std::vector is an array. However the internal representation of std::map is a red-black tree.

Damnit, I got ninja'd by sneftel twice.

Share on other sites
Isn't that going to really slow to pass glGenTextures a lot of times?

Share on other sites
I don't know. How many times do you plan to call it? If it's less than "a bazillion", then no, it won't be noticeably slow. Certainly it takes much less time to generate the texture name than it will to load the texture data in.

Share on other sites
Okay I was just making sure, and really it won't make a difference in the way of gameplay... just initial load time.

Share on other sites
Quote:
 Original post by NiddlesThe error is:texture.cpp:77: error: passing const std::map, std::allocator > >' as this' argument of _Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = std::string, _Tp = GLuint, _Compare = std::less, _Alloc = std::allocator >]' discards qualifiers

What an incredibly impenetrable error message. Which compiler gave you that?

Share on other sites
Quote:
Original post by Cantos
Quote:
 Original post by NiddlesThe error is:texture.cpp:77: error: passing const std::map, std::allocator > >' as this' argument of _Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = std::string, _Tp = GLuint, _Compare = std::less, _Alloc = std::allocator >]' discards qualifiers

What an incredibly impenetrable error message. Which compiler gave you that?

The error message isn't really that impenetrable. The error actually boils down to:

'x' as this' argument of operator[] discards qualifiers.

'x' is simply an expansion of the template class's type, which happens to consist of several nested template expressions. You don't have to decode every bit of 'x', you just need to be able to pick out that 'x' is of type std::map.

Just about any compiler would have produced similar output. Being able to descipher the error just takes some practice, or you can use a tool to help descipher template error messages ... if you're a pussy :P

[Edited by - fpsgamer on May 28, 2008 9:05:41 PM]

Share on other sites
I don't know about that ...

VC++ 2005 EE is more concise.
#include <map>

class Broken
{
int get () const
{
return contains[0];
}
std::map<int,int> contains;
};

int main ()
{
}

error C2678: binary '[' : no operator found which takes a left-hand operand of type 'const std::map<_Kty,_Ty>' (or there is no acceptable conversion)

Share on other sites
Quote:
 Original post by CantosI don't know about that ... VC++ 2005 EE is more concise.*** Source Snippet Removed ***error C2678: binary '[' : no operator found which takes a left-hand operand of type 'const std::map<_Kty,_Ty>' (or there is no acceptable conversion)

I didn't say the error message couldn't be simplified. I conceded that point by giving a link to a tool that can simplify template errors if your compiler doesn't are already.

But it isn't impenetrable as long as you have a slight understanding of template expansion.

Also, I should add "... discards qualifiers" isn't exactly a mysterious error, as it indicates the error has to do with "cv-qualifiers", which it does.