Custom container iterators ensure that ADL considers the std namespace?

I am not going to use this in real code. I promise.

Does the standard ensure that the std is found if the function argument is of type container::iterator and container::iterator not a typedef for the 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 an iterator class be defined in such a namespace that std will not be considered by ADL?

Thanks in advance.

+7
source share
2 answers

I believe that the answer matters no in the most general case, but yes for most practical implementations.

In accordance with ISO C ++, Section 3.4.2 / 2, there is the concept of a β€œlinked namespace” for an argument, which is defined in a way that includes

If T is a type of class (including unions), its associated classes: the class itself; the class he is a member of, if any ; and its direct and indirect base classes. Its associated namespaces are namespaces in which related classes are defined.

This suggests that if the iterator type is really a nested type inside some container, such as std::set , then the associated namespace for this iterator when calling find is std , since std::set is the associated class and std is namespace containing set . Then the standard says that (& sect; 3.4.2 / 2a)

If a regular unqualified name lookup finds a declaration of a member function of a class, the associated namespaces and classes are not considered. Otherwise, the set of declarations found when searching for the name of the function is a combination of the set of found declarations using the usual unqualified search and the set of declarations found in namespaces and classes associated with argument types .

That would mean that you would really find the find function in namespace std .

However, this is not guaranteed in general. We also have from spec (& sect; 3.4.2) that

Typedef names and use-declarations used to indicate types do not contribute to this set.

So, as you mentioned in your question, if the type of the iterator is a kind of typedef , this does not guarantee proper operation. But if it is not, it seems that if you know that the type is not typedef, it should be in namespace std or nested in a class in namespace std and should be raised for ADL. But do not do it! :-)

+5
source

Exact type ::iterator etc. for standard containers is determined by the implementation, so theoretically there is nothing that would prevent it from being typedef something outside of std:: (for example, a simple pointer).

I cannot find anything else in the standard that says that ADL will always work in this case, so - if someone does not correct me - I will have to say that the answer is no, you can assume that find will be found through ADL.

+5
source

All Articles