次のコードを検討してください。
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
の宣言セットです。
私はこの手順に従っていることを試みておりC
、derived
inをf
使用しています。base
base foo()
「宣言セット」は次のように定義されていp3
ます。
S(f, C)と呼ばれるinのルックアップ セットは、2 つのコンポーネント セットで構成されます。[...]
f
C
f
p4
宣言セットに何が入るかを示します。
C
name の宣言が含まれている場合f
、宣言セットには、ルックアップが発生する言語構造の要件を満たすすべてのf
defined inの宣言が含まれます。C
using base::base
( )内の名前base
( f
)の宣言です。このパラグラフは、ルックアップが発生する言語構造の要件を宣言が満たさないことが何を意味するかの例を示していますが、このルックアップから除外されるものは何もありません。derived
C
using 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-specifier、evalated-type-specifier、またはbase-specifierに現れる名前が含まれます。
これらのどれも問題の名前検索には当てはまらないので、この段落が適用され、コンストラクターを指定していると私には思われますusing base::base
(継承コンストラクター宣言であることを考えると、これは直感的に予想されることでもあります)。
派生クラス スコープで (基本クラス コンストラクターを指定する) 宣言を見つけたので、次の手順を続けます[class.member.lookup] p4
。
結果の宣言セットが空でない場合、サブオブジェクト セットには
C
それ自体が含まれ、計算は完了します。
つまり、名前のルックアップは派生クラスのスコープで結果を見つけたので、基本クラスのスコープ ( injected-class-name base
が見つかる場所) の検索には進みません。[余談ですが、名前のルックアップが基本クラスのスコープに続いたとしても、コンストラクターと注入されたクラス名の間を明確にするものは何もありません]。
私の推論はどこが間違っていますか?