3

Stroustrup book (第 4 版) の 396 ページと 397 ページにある引数依存ルックアップ (ADL) の例を以下に再現します。

namespace N {
    struct S { int i; };
    void f(S);
    void g(S);
    void h(int);
};

struct Base {
    void f(N::S);
};

struct D : Base {
    void mf(N::S);

    void g(N::S x)
    {
        f(x);   // call Base::f()
        mf(x);  // call D::mf()
        h(1);   // error: no h(int) available
    }
};

上記のコメントが言っていることは正しいですが (私はそれをテストしました)、次の段落で著者が言っていることとは一致していないようです:

標準では、引数依存のルックアップのルールは、関連付けられた名前空間の観点から表現されています(iso §3.4.2)。基本的:

  • 引数がクラス メンバーの場合、関連する名前空間は、クラス自体 (その基本クラスを含む) と、クラスを囲む名前空間です。
  • 引数が名前空間のメンバーである場合、関連付けられた名前空間はそれを囲む名前空間です。
  • 引数が組み込み型の場合、関連付けられた名前空間はありません。

例ではx、 typeN::Sは class のメンバーでDも、その baseのメンバーでもありませんBase。しかし、それはのメンバーですnamespace N。上記の 2 番目の箇条書きによると、関数N::f(S)は ではなく、呼び出される関数である必要がありBase::f()ます。

上記の結果は、標準の段落 3.4.2p2 の 2 番目の箇条書きとも一致していないようです。

T がクラス型 (共用体を含む) の場合、関連するクラスは次のとおりです。 クラス自体。もしあれば、それがメンバーであるクラス。およびその直接および間接基本クラス。関連する名前空間は、関連するクラスがメンバーになっている名前空間です。さらに、T がクラス テンプレートの特殊化である場合、それに関連付けられた名前空間とクラスには次のものが含まれます。テンプレート テンプレート引数がメンバーである名前空間。テンプレート テンプレート引数として使用されるメンバー テンプレートがメンバーであるクラス。

4

1 に答える 1

4

3.4.2/3X非修飾ルックアップ (3.4.1) によって生成されたルックアップ セットと、引数依存ルックアップ (次のように定義) によって生成されたルックアップ セットとしYます。X含まれている場合

  • クラスメンバーの宣言、または
  • using 宣言ではないブロック スコープの関数宣言、または
  • 関数でも関数テンプレートでもない宣言

Y は空です。さもないと...

したがって、基本的に、通常のルックアップでメンバー関数またはローカル (ブロック スコープ) 関数宣言 (または関数ではないもの) が見つかった場合、ADL は起動しません。通常のルックアップでスタンドアロンの名前空間スコープ関数が見つかった場合、または何も見つからなかった場合に開始されます。

于 2013-10-06T14:15:29.207 に答える