Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling map::find with a const argument

Tags:

c++

constants

I have an object:

map<A*, string> collection;

I would like to call the map::find function, but the value I have for the key is const, like in the following code, which does not compile:

const A* a = whatever();
collection.find(a);

The following code works and performs the equivalent of the find operation:

const A* a = whatever();
map<A*, string>::iterator iter;
for(iter = collection.begin(); iter != collection.end(); ++iter)
    if(iter->first == a)
        break;
// iter now contains the result or map::end (just like map::find)

But it is probably not as efficient as the find member function, and it's also ugly and masks the intent of the code.

How can I call the find function?

Thanks

Edit:

I am intentionally using a pointer type for the key in the map. The behaviour I want is for the map to use pointer equality for the keys. (Just like in my loop code)

like image 744
bartsimpson Avatar asked Sep 29 '10 00:09

bartsimpson


2 Answers

Comparing pointers has nothing to do with it. The OP may or may not need a custom compare operation; it looks to me like they're just looking for a specific object by its address, which seems perfectly reasonable. The first two answers seem to have missed the point that find() doesn't compile while a handwritten search works.

The find() call won't compile because you're passing it the wrong type to search for. map::find() expects its argument to be the same type as the map's key type, which is A*. You're passing a const A*, which is not implicitly convertible to an A* (but is comparable to an A*, which is why the handwritten search works). The implicit conversion only works in the other direction (A* to const A*, not const A* to A*).

Possibly you should be using const A* instead of A* as the map key; depending on what you're using the map for, this may or may not be practical. If you need the map key to be A*, you need to pass an A* to find(), which means either starting with an A* as your search target in the first place, or if you can only get it from its original source as a const A*, using find(const_cast<A*>(a)) to turn it into a pointer to non-const (which is not the same as a non-const pointer, a point that confuses a lot of C/C++ coders). Usually const_cast is inadvisable, but here it's safe since you're only comparing the pointer, not dereferencing it.

like image 134
Ross Smith Avatar answered Nov 07 '22 07:11

Ross Smith


You can always remove the const

const A* a = whatever();
collection.find( const_cast<A*>(a) );
like image 1
Michael Anderson Avatar answered Nov 07 '22 07:11

Michael Anderson