1

次のコードを検討してください。

struct base {};

struct derived : public base {
    using base::base;
    base foo() const;  // how does name lookup on 'base' here work?
};

直観的に、このコードが有効であることは明らかであり、コンパイルされます (gcc と clang でテスト済み)。

ただし、標準の何が有効かを理解したいと思います。base具体的には、 inの名前検索base foo()が、継承されたコンストラクターではなく基本クラスの型を見つける方法を理解したいと思います。

これは、標準的な言葉遣いの私の分析であり、コンストラクターに解決される必要があることを示しています。おそらく間違っていると思いますが、どこが間違っているのかを理解したいと思います。

私はから始めました[class.member.lookup] p1

メンバー名のルックアップは、クラス スコープ内の名前 ( id-expression )の意味を決定します。[...] id-expression の場合、名前の検索は のクラス スコープで開始されます。this

p7名前検索の結果は次のとおりです。

f[a class scope] 内の [a member name] の名前検索の結果は、 S(f, C)Cの宣言セットです。

私はこの手順に従っていることを試みておりCderivedinをf使用しています。basebase foo()

「宣言セット」は次のように定義されていp3ます。

S(f, C)と呼ばれるinのルックアップ セットは、2 つのコンポーネント セット構成されます。[...]fCf

p4宣言セットに何が入るかを示します。

Cname の宣言が含まれている場合f、宣言セットには、ルックアップが発生する言語構造の要件を満たすすべてのfdefined inの宣言が含まれます。C

using base::base( )内の名前base( f)の宣言です。このパラグラフは、ルックアップが発生する言語構造の要件を宣言が満たさないことが何を意味するかの例を示していますが、このルックアップから除外されるものは何もありません。derivedCusing base::base

次に、宣言セット内のusing 宣言p3がどのように処理されるかについて説明します。

宣言セットでは、使用宣言は、派生クラスのメンバーによって非表示またはオーバーライドされていない指定されたメンバーのセットに置き換えられます。

それで、どのメンバーがusing base::base指定しますか?私には、それが次のように答えられているようです[class.qual] p2

関数名が無視されず、 nested-name-specifierが classを指定するルックアップではC:

  • で検索したときに、ネストされた名前指定子の後に指定された名前Cが、の注入されたクラス名であるC場合、または

  • member-declarationであるusing-declarationで、 nested-name-specifier の後に指定された名前が、 nested-name- specifierの最後のコンポーネントの識別子[...]と同じ場合

代わりに、名前は class のコンストラクターに名前を付けると見なされCます。

「関数名が無視されないルックアップ」の意味を明確にする脚注があります。

関数名が無視されるルックアップには、nested-name-specifierevalated-type-specifier、またはbase-specifierに現れる名前が含まれます。

これらのどれも問題の名前検索には当てはまらないので、この段落が適用され、コンストラクターを指定していると私には思われますusing base::base(継承コンストラクター宣言であることを考えると、これは直感的に予想されることでもあります)。

派生クラス スコープで (基本クラス コンストラクターを指定する) 宣言を見つけたので、次の手順を続けます[class.member.lookup] p4

結果の宣言セットが空でない場合、サブオブジェクト セットにはCそれ自体が含まれ、計算は完了します。

つまり、名前のルックアップは派生クラスのスコープで結果を見つけたので、基本クラスのスコープ ( injected-class-name baseが見つかる場所) の検索には進みません。[余談ですが、名前のルックアップが基本クラスのスコープに続いたとしても、コンストラクターと注入されたクラス名の間を明確にするものは何もありません]。

私の推論はどこが間違っていますか?

4

1 に答える 1

4

標準では、コンストラクターには name がないことを指摘するのに苦労しています。名前がないため、名前検索では見つかりません。

C++11 §12.1/1

コンストラクタには名前がありません

C+11 §12.1/2

コンストラクターには名前がないため、名前の検索中にそれらが検出されることはありません。

于 2016-01-08T07:54:46.400 に答える