名前探索
名前探索は、プログラム中で名前に遭遇した際に、その名前を導入した宣言と関連付ける手続きです。
例えば、std::cout << std::endl; をコンパイルするために、コンパイラは以下を実行します。
stdという名前に対する非修飾名探索。これによりヘッダ <iostream> 内の名前空間 std の宣言が見つかります。coutという名前に対する修飾名探索。これにより名前空間std内の変数宣言が見つかります。endlという名前に対する修飾名探索。これにより名前空間std内の関数テンプレート宣言が見つかります。operator<<という名前に対する実引数依存の名前探索。これにより名前空間std内の複数の関数テンプレート宣言が見つかります。また、std::ostream::operator<< という名前に対する修飾名探索も行われ、これによりクラス std::ostream 内の複数のメンバ関数宣言が見つかります。
関数名および関数テンプレート名に対して、名前探索は同じ名前を持つ複数の宣言を関連付けることができ、実引数依存の名前探索から追加の宣言を得ることもあります。テンプレート実引数推論も適用される可能性があり、その宣言集合はオーバーロード解決に渡され、使用される宣言が選択されます。適用可能な場合、メンバアクセス規則は、名前探索とオーバーロード解決の後にのみ考慮されます。
その他すべての名前(変数、名前空間、クラスなど)に対して、名前探索が複数の宣言を関連付けられるのは、それらが同じ実体を宣言している場合に限られます。そうでなければ、プログラムがコンパイルされるためには単一の宣言を生成しなければなりません。あるスコープでの名前の探索は、その名前のすべての宣言を見つけますが、一つの例外があり、「struct ハック」または「型/非型隠蔽」として知られています。同じスコープ内で、ある名前の出現がtypedefではないクラス/構造体/共用体/列挙型の宣言を参照し、同じ名前の他のすべての出現が、すべて同じ変数、非静的データメンバ、または列挙子を参照するか、あるいはすべてがオーバーロードされた可能性のある関数または関数テンプレート名を参照する場合があります。この場合、エラーにはなりませんが、型名は探索から隠蔽されます(コードはそれにアクセスするために詳細型指定子を使用しなければなりません)。
[編集] 探索の種類
名前がスコープ解決演算子 :: の直右に現れる場合、または :: の後に曖昧性解消キーワード template が続く可能性がある場合は、以下を参照してください。
それ以外の場合は、以下を参照してください。
- (関数名の場合、実引数依存の名前探索を含みます)
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 2063 | C++98 | 「struct ハック」がクラススコープに適用されなかった(Cとの互換性を壊す) | 適用済み |
| CWG 2218 | C++98 | 非関数(テンプレート)名の探索が、複数の宣言を関連付けられなかった たとえそれらが同じ実体を宣言していても |
許可 |
[編集] 関連項目
- スコープ
- 実引数依存の名前探索 (ADL)
- テンプレート引数の推論
- オーバーロード解決
| C ドキュメントの名前探索と名前空間
|