Ответ 1
Причина в том, что существует стандартный алгоритм std:: distance, который найден ADL (зависимым от аргумента): хотя ваш вызов не соответствует пространству имен std
, тип ваших аргументов a
и b
(т.е. std::string
) живет в том же пространстве имен, что и функция std::distance
(т.е. std
), и поэтому std::distance()
также рассматривается для разрешения перегрузки.
Если вы действительно хотите вызвать свою функцию distance()
(я бы предложил вам не делать этого), вы можете либо поместить ее в свое пространство имен, а затем полностью квалифицировать имя функции при ее вызове или оставить ее в глобальном пространстве имен и вызовите его следующим образом:
::distance(a, b);
// ^^
Обратите внимание, однако, что только ADL не может привести к сбою компиляции вашей программы, если ваша реализация Стандартной библиотеки предоставляет версию SFINAE iterator_traits
(более подробную информацию в fooobar.com/info/377866/... - любезно предоставлено MooingDuck).
При реализации iterator_traits
, совместимой с SFINAE, ваш компилятор должен признать, что шаблон функции std::distance()
(потому что это шаблон) не может быть создан при заданных аргументах типа std::string
из-за его возвращаемого типа:
template< class InputIt >
typename std::iterator_traits<InputIt>::difference_type
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Trying to instantiate this with InputIt = std::string
// may result in a soft error during type deduction if
// your implementation is SFINAE-friendly, and in a hard
// error otherwise.
distance( InputIt first, InputIt last );
В этом случае компилятор просто отменит этот шаблон для целей разрешения перегрузки и выделит вашу функцию distance()
.
Однако, если ваша реализация Стандартной библиотеки не обеспечивает версию SFIFAE для iterator_traits
, может произойти сбой замены в контексте, который не подходит для SFINAE, что приводит к ошибке (жесткой) компиляции.
Этот живой пример показывает вашу исходную компиляцию программы с помощью GCC 4.8.0, которая поставляется с версией libstdС++, который реализует SFINAE-дружественный iterator_traits
.