Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are pointers allowed as keys in ordered STL containers?

There's this other question asking about how comparing pointers is supposed to be interpreted wrt the C++ Std.

So I was wondering what the C++ Std has to say about using pointers as keys in ordered standard library (STL) containers -- i.e. is one allowed to have

std::map<T1*, T2>

and is this due to the specification of std::less or builtin operator <?

like image 513
Martin Ba Avatar asked Feb 06 '11 12:02

Martin Ba


People also ask

Can I use a pointer as a key map?

Pointers can be used as keys but especially with a std::map (or std::set) I would not advise it. The behavior of the program is not deterministic i.e. when one iterates over the map the order in which the items in the map are iterated is not guaranteed to be the same.

What type of STL container consists of a collection of key value pairs?

Associative containers Provides a collection of 1-to-1 mappings, i.e. a collection of key/value "pairs" (pair objects) in which the first element of such a pair is a key and the second element of the pair is the value corresponding to that key, and the pair objects are maintained in sorted key order.

Which of the following is NOT container type in STL?

Iterators. Which of the following is not an STL container type? Container adapters.


2 Answers

Yes, because it uses std::less, which is required to result in a total order even if < doesn't. (< would be allowed to treat different pointers from distinct sequences as equal, which would result in an odd behaviour of map etc if you insert pointers from different sequences).

like image 76
etarion Avatar answered Nov 11 '22 01:11

etarion


I'd like to add another reason to not do this. If you are using pointers in this way, and if you happen to have a bug that depends on the ordering of the elements of a container, then it will be very difficult to find. Even if your program seems to be completely deterministic, it will not be. The order of the elements in a container depends on the algorithm the memory allocator uses, which is completely out of your control. If you run the same example muliple times without restarting your program, some may fail and others succeed.

This is the voice of bitter experience. I did this with a debugger project once, where I had containers filled with C++ symbols. When I needed to sort the symbols, I ended up with symbols which are different, but which have the same name (think overloaded functions) and which were identical in all other respect. So, in this case I compared them as a last resort by the address of the symbol object. I ran into several bugs which were apparently non-deterministic, where the non-determinism was caused by just this phenomenon. Sometimes it took more than 10 or 15 attempts to reproduce the problems. I eventually took the time to eliminate sorting by addresses, and that saved me a lot of trouble over the longer term.

With that said, I won't say I haven't done this recently. But every time I do it I feel like it's a mistake.

like image 20
Bill White Avatar answered Nov 11 '22 01:11

Bill White