Поиск имени и разрешение перегрузки различаются. Имя должно быть сначала найдено в области видимости, то есть мы должны найти X
, чтобы имя do_stuff
было разрешено до X::do_stuff
- независимо от использования имени, - а затем разрешение перегрузки выбирает между различнымиобъявления X::do_stuff
.
Процесс НЕ должен идентифицировать все такие видимые случаи A::do_stuff
, B::do_stuff
и т. д., а затем выполнить разрешение перегрузки среди объединения этого. Вместо этого для имени должна быть указана одна область.
В этом коде:
struct Baz : public Foo, public Bar
{
void func ()
{
do_stuff (1.1f); // ERROR HERE
}
};
Baz
не содержит имени do_stuff
, поэтому можно искать базовые классы,Но имя встречается в двух разных базах, поэтому поиск имени не может определить область. Мы никогда не добираемся до разрешения перегрузки.
Предлагаемое исправление в другом ответе работает, потому что оно вводит имя do_stuff
в область действия Baz
, а также вводит 2 перегрузки для имени. Таким образом, поиск имени определяет, что do_stuff
означает Baz::do_stuff
, а затем разрешение перегрузки выбирается из двух функций, которые известны как Baz::do_stuff
.
В качестве shadowing другое следствие поиска имени (не само по себе правило). Поиск имени выбирает внутреннюю область, и поэтому все, что находится во внешней области, не совпадает.
Еще один усложняющий фактор возникает, когда зависимый от аргумента поиск находится в игре. Чтобы подвести итог очень кратко, поиск имени выполняется несколько раз для вызова функции с аргументами типа класса - базовая версия, как описано в моем ответе, а затем снова для каждого типа аргумента. Затем объединение найденных областей переходит в набор перегрузки. Но это не относится к вашему примеру, поскольку ваша функция имеет только параметры встроенного типа.