Мне кажется, что есть две функции-кандидата для вызова 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) у нас в наборе Икс декларация 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), который лучше подходит.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]