Я взял следующий пример из Вот.
namespace NS
{
class A {};
void f( A *&, int ) {}
}
int main()
{
NS::A *a;
f( a, 0 ); //calls NS::f
}
Я сталкивался с этим, когда пытался найти функции расширения в C ++.
Означает ли приведенный выше пример просто, что если я вызову любую функцию с первым аргументом в качестве объекта любого класса и если эта функция не найдена в текущем пространстве имен, то компилятор найдет требуемую функцию в пространстве имен первого объекта?
Если я ошибаюсь, этот вопрос, кажется, не связан, но метод расширения в C # есть какие-то отношения с ADL?
Вы спрашивали:
Означает ли приведенный выше пример просто, что если я вызову любую функцию с первым аргументом в качестве объекта любого класса и если эта функция не найдена в текущем пространстве имен, то компилятор найдет требуемую функцию в пространстве имен первого объекта?
Ответ:
Используя ADL, компилятор найдет все функции, которые являются потенциальными кандидатами. Он находит точно один, он будет использовать его. Если он найдет более одного, произойдет ошибка. Он не использует ADL, только если не может найти функцию в текущем пространстве имен.
Пример 1:
#include <iostream>
using namespace std;
namespace NS1
{
struct A {};
int foo(A a) { return 10; }
}
namespace NS2
{
struct A {};
int foo(A a) { return 20; }
}
int main()
{
cout << foo(NS1::A()) << endl; // Resolves to NS1::foo by using ADL
cout << foo(NS2::A()) << endl; // Resolves to NS2::foo by using ADL
}
Пример 2:
#include <iostream>
using namespace std;
namespace NS1
{
struct A {};
}
int foo(NS1::A a) { return 10; }
namespace NS2
{
struct A {};
int foo(A a) { return 20; }
}
int foo(NS2::A a) { return 30; }
int main()
{
cout << foo(NS1::A()) << endl; // Resolves to ::foo(NS1::A)
cout << foo(NS2::A()) << endl; // Unable to resolve.
// ::foo(NS2::A) and NS2::foo(NS2::A) are
// equally valid candidates.
}