Мне кажется, что есть две функции-кандидата для вызова g(parm, 1) в примере из [basic.lookup.argdep]/3

Пример в [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) мы имеем в множестве X объявление void g(NS::T, float); в глобальном масштабе. AFAICT, мы также имеем в наборе Y декларацию void g(T, int); в пространстве имен NS, ассоциированное пространство имен аргумента parm типа NS::T, Таким образом, если я не ошибаюсь, две декларации являются кандидатами для разрешения перегрузки. Тогда, это тот случай, когда объявление в глобальной области видимости предпочтительнее по отношению к объявлению в пространстве имен NS? Зачем? Я был бы очень признателен за цитату из стандарта в качестве ответа.

1 ответ

Решение

В этом разделе мы имеем:

Позволять 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), который лучше подходит.

Другие вопросы по тегам