Причина заключается в том, что стандартный алгоритм называется std::distance существует, которое находится ADL (Довод Dependent Lookup): хотя ваш звонок не квалифицирован с std
именами, типа ваших аргументов a
и b
(т.е. std::string
) жизни в том же пространстве имен, что и функция std::distance
(то есть std
), и поэтому std::distance()
также рассматривается для разрешения перегрузки.
Если вы действительно хотите позвонить своей функции distance()
(я бы предложил вам не делать этого), вы можете либо поместить ее в свое пространство имен, а затем полностью квалифицировать имя функции, когда вы ее вызываете, или оставить ее в глобальное пространство имен и вызывать его таким образом:
::distance(a, b);
// ^^
Обратите внимание, однако, что ADL в одиночку может не причина, чтобы ваша программа не в состоянии компиляции, если ваша реализация стандартной библиотеки обеспечивает SFINAE-дружественную версию iterator_traits
(более подробнее в this Q&A on StackOverflow - любезно предоставлено MooingDuck).
С SFINAE безвредной реализации iterator_traits
, компилятор должен признать, что шаблон по 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()
.
Однако, если ваша реализация Стандартной библиотеки не предоставляет SFINAE-совместимую версию iterator_traits
, отказ замены может произойти в контексте, который не подходит для SFINAE, что приводит к ошибке (жесткой) компиляции.
В этом live example показана исходная компиляция программы с помощью GCC 4.8.0, которая поставляется с версией libstdC++, которая реализует SFINAE-дружественный iterator_traits
.
Я сразу понял, в чем проблема. Если бы я был здесь только 3 часа назад. Lol – 0x499602D2