0

最近、ADLに関するSOについていくつか質問があり、私は考えさせられました。基本的に、ADLを実行するときにコンパイラが検索できるヘッダーファイルはわかりませんか?それはユーザーのコードに含まれているものだけですか、それともユーザーのコードで使用されているのと同じ名前空間を持つ他のヘッダーファイルを含めることができますか?例えば。std名前空間は複数のヘッダーファイルにまたがっています。ただし、その一部のみを含めることができます。stdここで、ヘッダーファイルのこのサブセットには含まれていないが、名前空間(インクルードしていないファイル)にはある関数を定義した場合でも、あいまいな呼び出しになりますか?私は主にこの質問に関する議論のためにこの疑問を抱きました

4

5 に答える 5

4

仕組みは次のとおりです...ソースを実行可能ファイルにコンパイルするには、3つの基本的な手順があります。

  1. 前処理
  2. コンパイル
  3. リンク

C ++では、これらのステップで重複はありません。インクルードディレクティブはプリプロセッサディレクティブであるため、コンパイル前に発生します。テンプレートのインスタンス化はコンパイルの一部であるため、前処理後に行われます。コンパイラは、現在の変換ユニットの外部で何かを検索することはありません。したがって、コンパイル時のイベントであるADLは、含まれていないヘッダーを検索できません。

バズへのコメントにリンクされているコードの問題は、標準ヘッダーに含まれているヘッダーと含まれていないヘッダーがわからないことです。(まあ、あなたがそれらを調べて見つけるかどうかを知ることができますが、標準は言いません。)あなたのヘッダーのどれもが含むことができ、そして明らかに含まれてい<algorithm>ました。それが起こったら:

http://www2.roguewave.com/support/docs/leif/sourcepro/html/stdlibref/merge.html

namespace stdADLが原因で、バージョンの定義の1つがあいまいになります。

于 2011-02-04T17:35:30.933 に答える
1

いいえ。定義を含むヘッダーを含めない限り(または定義を含む別のヘッダーを含むヘッダーを含めない限り)、あいまいな呼び出しはありません。C ++標準バージョンが含まれていない限り、独自のiostream、文字列、ベクトルなどを定義できます(std名前空間の他の部分が含まれている可能性があるにもかかわらず)。

于 2011-02-04T17:26:18.083 に答える
1

ADLは、純粋にルックアップルールに関するものです。すべての名前ルックアップと同様に、以前に宣言されたエンティティのみを見つけることができるため、ヘッダーファイルが特定の宣言が発生する唯一の場所であり、そのヘッダーファイルが直接または間接的に(まだ)インクルードされていない場合、その宣言は、ADLの有無にかかわらず表示されません。

(これは、ルックアップされる名前がテンプレート定義の依存式であるかのように、完全には当てはまりません。テンプレートの特殊化がインスタンス化されるまで、最終的なルックアップは発生しません。インスタンス化された場合、後続の宣言がルックアップの結果に影響を与える可能性があります。 )。

All(!)ADLは、関数呼び出し式でunqualified-idを照合しようとしたときに検索される名前空間を拡張して、関数呼び出し式のパラメーターに「関連する」名前空間を含めます。

于 2011-02-04T17:35:50.570 に答える
1

C ++標準は、各インクルードファイルが取り込む名前を定義しますが、それらだけが使用可能になる名前になるとは限りません。

これは、理論的には、含めるだけで<vector>利用できるようになる可能性があることを意味しますstd::map

これは残念なことです

  1. インクルードファイルが欠落しているために正しくないコードは、特定の実装のインクルードファイル間の依存関係が移植できないため、とにかくコンパイルできます。

  2. 名前のいずれかがの名前でもある場合、ADLが原因でルックアップの問題が発生する可能性がありますstd。これは、移植性の問題として現れることもあります。

あなたの質問に明確に答えるために:ADLは見られたインクルードファイルのみを参照しますが、実装では標準ファイルが別の標準ファイルをインクルードすることが許可されているため、それらがどれであるかを移植的に知ることはできません。

したがって、ADLはすべての可能な標準ヘッダーを見ることができますが、それを当てにすることはできません。

于 2011-02-04T17:59:07.163 に答える
0

コンパイラは通常、単一の変換ユニットで動作します。つまり、プリプロセッサがパスを通過したの入力のすべてのソースコードです。その時点で、すべてのヘッダーはすでに再帰的に展開されています。特定のライブラリヘッダーファイルをインクルードする場合、他のファイルなどを想定することはできません。いつでも確認できますが、これは「実装の詳細」であると確信しています。

于 2011-02-04T17:28:52.430 に答える