概要
Microsoft Visual C (MSVC) ) は、2 フェーズ テンプレートのインスタンス化の実装に欠陥があるとのことで、しばしば批判されてきました。この記事では、この批判の詳細を掘り下げ、根本的な問題を検討し、詳細な説明を提供します。
2 フェーズ テンプレートのインスタンス化論争
2 フェーズ テンプレートのインスタンス化これは、テンプレート クラスと関数が最初に構文的に正しいかどうかチェックされ、その後の使用サイトで完全なインスタンス化が行われる C のプロセスです。ただし、MSVC がこのメカニズムを適切に実装していないとの主張もなされています。
問題の早期理解
当初、MSVC は基本的な構文チェックのみを実行すると考えられていました。テンプレート定義では、テンプレートで使用される名前が宣言されているかどうかは無視されます。ただし、この理解は不完全です。
問題の本当の性質
MSVC の 2 フェーズ テンプレートのインスタンス化に関する実際の問題は、相互接続された 2 つの層で構成されています。
レイヤー 1: 間違った第 1 フェーズLookup
MSVC は、次の例のように、非依存式の初期 (第 1 フェーズ) ルックアップの実行に失敗します。
int foo(void*); template<typename T> struct S { S() { int i = foo(0); } }; void foo(int);
MSVC は、このルックアップを第 2 フェーズに延期します。ここで、誤って式を「foo(int)」にバインドしてしまい、 error.
レイヤー 2: 不正な第 2 フェーズ ルックアップ
MSVC のテンプレート ルックアップの第 2 フェーズにも欠陥があります。 C 標準では、ADL で指定された名前空間が第 2 フェーズで拡張されると指定されていますが、MSVC は誤って非 ADL ルックアップも拡張します。
これは、次の例で説明できます。
namespace N { struct S {}; } void bar(void *) {} template <typename T> void foo(T *t) { bar(t); } void bar(N::S *s) {}
依存しているにもかかわらず、bar(t) への呼び出しは誤って void bar(N::S *s) に解決され、不適切な動作を示しています。 MSVC の第 2 フェーズ ルックアップ。
結論
Microsoft Visual C の 2 フェーズ テンプレートのインスタンス化の実装には確かに欠陥がありますが、当初理解されていた単純化された方法ではありません。問題は、誤った第 1 フェーズ ルックアップと第 2 フェーズ ルックアップの間の複雑な相互作用であり、特定のコード構造でエラーや誤った動作が発生する可能性があります。
以上がMicrosoft Visual C の 2 フェーズ テンプレートのインスタンス化は本当に壊れていますか? 壊れている場合はどのようにすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。