Я полагаю, что ответ нет в самом общем случае, но да для большинства практических реализаций.
В соответствии со стандартом ISO C ++, раздел 3.4.2 / 2, существует понятие «связанного пространства имен» для аргумента, которое определяется таким образом, что включает в себя
Если T является типом класса (включая объединения), его ассоциированными классами являются: сам класс; класс которого это
член, если есть ; и его прямые и косвенные базовые классы. Связанные пространства имен являются пространствами имен
в котором определены связанные с ним классы.
Это говорит о том, что если тип итератора действительно является вложенным типом внутри некоторого контейнера, например std::set
, то ассоциированное пространство имен для этого итератора при вызове find
будет std
, поскольку std::set
является связанный класс и std
- это пространство имен, содержащее set
. Стандарт тогда говорит, что (& sect; 3.4.2 / 2a)
Если обычный неквалифицированный поиск имени находит объявление функции-члена класса, связанные пространства имен и классы не рассматриваются. В противном случае набор объявлений, найденных поиском имени функции, является объединением набора объявлений, найденных с использованием обычного неквалифицированного поиска, и набора
объявлений, найденных в пространствах имен и классах, связанных с типами аргументов .
Это будет означать, что вы действительно найдете функцию find
в namespace std
.
Тем не менее, не гарантированно будет работать в целом. Из спецификации (& 3.4;) мы также получаем, что
Имена типов и объявления-использования, используемые для указания типов, не участвуют в этом наборе.
Итак, как вы упомянули в своем вопросе, если тип итератора имеет вид typedef
, это не гарантирует правильной работы. Но, за исключением этого, кажется, что если вы знаете, что тип не является typedef, он должен быть в namespace std
или вложен в класс в namespace std
и должен быть выбран для ADL. Но не делай этого! : -)