Are pointers allowed as keys in ordered STL containers?

*爱你&永不变心* 提交于 2019-11-29 10:47:33

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).

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.

"They may valid but don't" is the answer I would give.

Obviously there is the issue of comparability that you raise, but the reason you don't want to is because of the lack of reference management on "vanilla" pointers. It's very easy for the object to be deleted without it being removed from the container, resulting in an invalid pointer and an access violation next time you go to access it.

Yes. Pointers are comparable via operator<().

If the pointers do not point to the elements of the same array or elements within the same object the c++ standard says the behavior is unspecified [expr.rel].

The standard says unspecified behavior means it's implementation defined [defns.unspecified].

If your compiler guaranties a strict weak order of pointers you can use any pointer with associative containers.

Most compilers do pointer comparison by comparing the memory addresses. On most architectures this comparison forms a strict weak order.

Therefore it's safe to use pointers as keys.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!