Параметр-зависимый поиск введен для поиска безоговорочного имени всех функций, а не только функций-друзей классов.
Вот демонстрационная программа
#include <iostream>
namespace N1
{
struct A
{
int a = 10;
friend void f( A &a ) { std::cout << "friend f( A & ) : A::a = " << a.a << '\n'; }
};
void f( const A &a ) { std::cout << "f( const A & ) : A::a = " << a.a << '\n'; }
}
int main()
{
N1::A a1;
f( a1 );
const N1::A a2;
f( a2 );
N1::f( a1 );
}
Вывод программы:
friend f( A & ) : A::a = 10
f( const A & ) : A::a = 10
f( const A & ) : A::a = 10
В этой программе, когда поиск по квалифицированному имени используется для функции с именем f и непостоянным объектом a1 в качестве аргумента, она называется функцией не-друга f, поскольку имя функции-друга f невидим в пространстве имен, где вводится его объявление.
Функции друзей включены в ADL, потому что если функция друга объявлена (и соответственно определена) только в классе, ее имя невидимо в пространстве имен, где объявление вводится напротив функций, которые объявлены в пространстве имен. Так, например, функции, не являющиеся друзьями, могут вызываться с использованием квалифицированных имен, в то время как функции-друзья, объявленные только в классах, не могут вызываться с использованием квалифицированных имен, поскольку они невидимы.
Для достижения того же действия с функциями, не являющимися друзьями сначала вы должны сделать их невидимыми в пространстве имен, где вводятся их объявления, и поиск по квалифицированному имени не должен их найти. Это невозможно без введения в стандарт C ++ некоторых новых понятий.