This question is, of course, not specific only to std::map, but that's what I've been working with so I'll focus on that.
The definition for std::insert allows:
iterator insert (iterator position, const value_type& val);
Where position is a hint. One can likewise emplace with a hint:
template <class... Args>
iterator emplace_hint (const_iterator position, Args&&... args);
The purpose of hints, of course, being so that std::map doesn't have to iterate through its red-black tree from the start, it can begin near its destination, dramatically reducing search time on a large tree.
So why does std::map::find not allow a hint?
iterator find (const key_type& k);
const_iterator find (const key_type& k) const;
Why must we search through the whole red-black tree with every find even if we know approximately where our lookup target will be?
-----------
In case you want a use case scenario...
-----------
In my particular case, I'm making a particular K-d tree class and its searchable node index is to be a std::map keyed off an class based around trinary bits, wherein:
0 = left-child
1 = no child
2 = right-child
The map would be, thusly, std::map<TrinaryKeyClass, KdTreeNode>
Such that a 1-dimensional case might have a key like:
02202111
... meaning "The key of the node representing left child's right child's right child's left child's right child". (Note that in a real-world case it'll generally be many-dimensional and with much longer keys, but we'll keep it simple here).
Since one doesn't know how deep the tree goes for an arbitrary element that we want to look up the node for, we have to iterate down to find the deepest layer. The logic flow for an element whose max-depth key would be 02202002 would thus be:
---
Does 01111111 exist (std::map::find)?
Yes, it does. Then does 02111111 exist (std::map::find)?
Yes, it does. Then does 02211111 exist (std::map::find)?
Yes, it does. Then does 02201111 exist (std::map::find)?
Yes, it does. Then does 02202111 exist (std::map::find)?
Yes, it does. Then does 02202011 exist (std::map::find)?
No, does not. Thus 02202111 is the deepest we can go. Return the iterator we were given when we ran std::map::find on 02202111.
---
The search could also be done non-linearly - for example, trying 02201111 first, then 02202011, then 02202111, and thus potentially saving lookup time. Either way, each iterator that we retrieve by our std::map::find is guaranteed to be "near" the iterator that we want to lookup next. With each step we progress, we get nearer and nearer the final destination. So obviously it only makes sense to want to pass this "hint" to std::map::find. Except, of course, we can't, because it doesn't appear to be in the standard, so each find has to search the tree from the beginning.
So, back to the original question:
1) Why is this not in the standard? Why only let some functions that do a search hint but not others? I'd think std::map::find would be the most obvious case where a person would want to give a hint....
2) What's the proper solution to this problem? Should I subclass std::map and implement my own std::map::find which takes a hint? It'd be ugly but if that's what I have to do...
Thanks :)
- kv, Karen