7

これは、引数依存のルックアップは名前空間またはクラスのみを検索しますか?からのフォローアップの質問です。、@DavidRodríguezは「ADLは型の囲んでいる名前空間を調べ、型自体の内部も調べます」と述べています。私は彼が言おうとしたことを間違えたかもしれませんが、私はこの例を試していました:

struct foo{
    static void bar(foo* z){}    
};

int main(){
    foo* z;
    bar(z);
}

コンパイルされず、エラー「'bar'はこのスコープで宣言されていません」が生成されます。ADLが静的メンバー関数を考慮しないのは事実ですか?つまり、関連するクラスの例では、fooADLはクラスの内部を調べないのでしょうか。。誰かがここでルールを単純化できますか?

4

1 に答える 1

6

彼はおそらくこれを意味しました:

struct foo{
    friend void bar(foo* z){}    //not static, its friend now
};

foo* z;
bar(z); //fine now

しかし、技術的には内部にbar()はありません。それはまだの囲んでいる名前空間にあります。 foofoo

-

編集:

彼が言ったfriendように、彼は確かに意味しました(私の強調):

最良の例は、型内で定義されているフレンド関数です。

そして彼の例はさらに説明しています。おそらく、「内部」だけでなく、「内部で定義」を読む必要があります。

関数の名前がクラスのスコープに導入されているように見えるため、「定義された」という単語が違いを生みますが、実際には、名前はの囲んでいる名前空間に導入されます(§3.3.1/3-を参照)。 4および§11.3/6)。 barbarfoo

より良い例を次に示します。

namespace Demo
{
     struct foo
     {
       friend void bar(foo* z){}
     };
}

foo *z;
bar(z); //foo (type of z) is inside Demo, so is bar
        //(even though bar is defined inside foo!)

bar(NULL);    //error - NULL doesn't help ADL.
bar(nullptr); //error - nullptr doesn't help ADL.

bar(static<foo*>(NULL)); //ok - ADL

名前空間にbar導入されたとしても、名前は非表示になっているため、通常の名前ルックアップを使用して外部から使用することはできないことに注意してください。Demo

using namespace Demo; //brings ALL (visible) names from Demo to current scope

bar(NULL); //STILL error - means bar is invisible

または、

Demo::bar(NULL);       //error - not found
Demo::foo::bar(NULL);  //error - not found

お役に立てば幸いです。

于 2013-02-06T09:12:03.577 に答える