0

hereから次の例を取り上げました。

namespace NS 
{
   class A {};
   void f( A *&, int ) {}
}
int main() 
{
   NS::A *a;
   f( a, 0 );    //calls NS::f
}

C ++で拡張関数を見つけようとしているときに、このようなものに出くわしました。

上記の例は、最初の引数を任意のクラスのオブジェクトとして関数を呼び出し、その関数が現在の名前空間で見つからない場合、コンパイラは最初のオブジェクトの名前空間で必要な関数を見つけることを意味しますか?

私が間違っていれば、この質問は無関係のように思えますが、C# の拡張メソッドはADL と関係がありますか?

4

1 に答える 1

2

あなたは尋ねました:

上記の例は、最初の引数を任意のクラスのオブジェクトとして関数を呼び出し、その関数が現在の名前空間で見つからない場合、コンパイラは最初のオブジェクトの名前空間で必要な関数を見つけることを意味しますか?

答え:

ADL を使用することにより、コンパイラは潜在的な候補となるすべての関数を見つけます。正確に 1 つが見つかり、それが使用されます。複数見つかった場合は、エラーになります。現在の名前空間で関数が見つからない場合にのみ、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.
}
于 2014-05-31T07:15:00.263 に答える