Функции в точке создания ищутся только с помощью зависимого от аргумента поиска (поиск функций в пространствах имен, связанных с аргументом функции).Обычный поиск выполняется только в точке определения шаблона.
Таким образом, для std::string
виден и вызывается только общий шаблон функции init
, поскольку в пространстве имен std
его нет.Для A
более конкретная функция находится в глобальном пространстве имен A
.
Если вы передадите объявление функции, специфичной для строки, до doSomething
, обычный неквалифицированный поиск найдет ее в определении и использует позже.
Если вы вызываете init
следующим образом, это запрещает поиск, зависящий от аргумента, и, таким образом, будет использовать общий шаблон для A
.
template <typename T>
void doSomething(T& t){
(init)(t);
// won't do ADL
}
(В качестве побочного узла: в этом случае не только поиск, зависящий от аргумента, запрещается при создании экземпляра, но init
не будет во-первых зависимым именем - только без скобоки неквалифицированные имена функций становятся зависимыми. Таким образом, в любом случае выполняется только поиск не-ADL определения, и вообще не выполняется поиск экземпляров, даже если бы там была форма, отличная от ADL, которая была бы там сделана.)