I have no intention of using this in real code. I promise.
Does the standard guarantee that std namespace is going to be found when a function argument is of type container::iterator and container::iterator isn’t a typedef for a built-in type?
For example
#include <set>
#include <algorithm>
int main()
{
std::set<int> s;
find(s.begin(), s.end(), 0); //do I have a guarantee that std::find will be found?
}
In other words, can the iterator class be defined in such a namespace that std won’t be considered by ADL?
Thanks in advance.
I believe that the answer is no in the most general case, but yes for most practical implementations.
According to the C++ ISO standard, §3.4.2/2, there is a notion of an “associated namespace” for an argument, which is defined in a way that includes
This suggests that if the iterator type is really a nested type inside of some container like
std::set, then an associated namespace for that iterator in the call tofindwould bestd, sincestd::setis an associated class andstdis the namespace containingset. The standard then says that (§3.4.2/2a)This would mean that you would indeed find the
findfunction innamespace std.However, this is not guaranteed to work in general. We also have from the spec (§3.4.2) that
So, as you mentioned in your question, if the iterator type is some sort of
typedef, this isn’t guaranteed to work correctly. But barring that, it appears that if you know that the type is not a typedef, it has to be innamespace stdor nested in a class innamespace stdand should get picked up for ADL. But don’t do it! 🙂