Пример в [Basic.lookup.argdep] / 3:
namespace NS {
class T { };
void f(T);
void g(T, int);
}
NS::T parm;
void g(NS::T, float);
int main() {
f(parm); // OK: calls NS::f
extern void g(NS::T, float);
g(parm, 1); // OK: calls g(NS::T, float)
}
Для вызова g(parm, 1)
у нас в наборе Икс декларация void g(NS::T, float);
в глобальном масштабе. AFAICT, у нас также есть в наборе Y декларация void g(T, int);
в пространстве имен NS
, ассоциированное пространство имен аргумента parm
типа NS::T
, Таким образом, если я не ошибаюсь, две декларации являются кандидатами для разрешения перегрузки. Тогда, это тот случай, когда объявление в глобальной области видимости предпочтительнее по отношению к объявлению в пространстве имен NS
? Зачем? Я был бы очень признателен за цитату из стандарта в качестве ответа.
В этом разделе мы имеем:
Позволять
X
быть набором поиска, произведенным неквалифицированным поиском, и пустьY
быть набором поиска, созданным зависимым от аргумента поиском (определенным следующим образом). ЕслиX
содержит
- объявление члена класса или
- объявление функции блока области видимости, которое не является используя декларирование, или же
- объявление, которое не является ни функцией, ни шаблоном функции
затем
Y
пустой.
Неквалифицированный поиск находит объявление функции области блока — extern void g(NS::T, float)
, Не декларация в глобальном масштабе ::g
,
Следовательно, Y
пусто, что делает союз X
а также Y
просто тривиально X
, который просто содержит одну декларацию, которая является жизнеспособным кандидатом.
Если бы этой декларации не было, то поиск без определения void g(NS::T, float)
и мы продолжаем выполнять ADL, который найдет N::g(T, int)
, который лучше подходит.
Других решений пока нет …