3
template<class T>
void foo()
{
    M
}

インスタンス化しない限り、VisualC++は上記のコードにエラーが含まれていることを通知しません。どうしてこれなの?

4

2 に答える 2

9

VisualC++にエラーがあるためです。2フェーズルックアップは実装されていません。インスタンス化しない場合でも、テンプレートの適切な構文をチェックすることになっていますが、それは行われません。

GCCはそれを受け入れません。それが必ずしも正しくないことを意味するとは限りませんが、とにかく何が起こるかについての例があります。

于 2012-07-21T05:36:20.103 に答える
7

C++ 標準には、この問題に関する非公式な説明が含まれています。これは、私が良いガイドラインになると考えていることを説明しており、多くの人が仕様によって暗示される規範的要件であると考えています。

ただし、実装は、「明白な」ルールが述べているように見えるものよりもさらに進んでいくことを可能にする、標準の規範的な部分を指すことができます。これについて以下に説明します。

非規範的な説明

標準では、実装がインスタンス化されるまでテンプレート定義をチェックしないことを許可しています。「テンプレート定義」が実際にテンプレート定義であると想定される場合についての正式な説明はありませんが、通常の実装では、「ブレースのバランス」/「括弧のバランス」の形式を実行します。定義の本体、最後の閉じ中かっこに到達するまでカウントします。間にあるものはすべて無視されます。

標準の例でこれがさらに明確になると思います

template<class T> class X {
  // ... (omitted) ...
  void g(T t) {
    +; // may be diagnosed even if X::g is not instantiated
  }
};

したがって、テンプレート定義の構文エラーまたは意味エラーを早期に診断することは、「実装の品質」です。


規範的な説明

これらのルールは、「診断不要」の品質です。注目に値するのは、これらのルールによる実装には、テンプレートがインスタンス化されていても、形式が正しくないテンプレート定義を診断しないというライセンスが付与されていることです。診断が不要なルールに違反した場合、実装はプログラム全体に対して自由に実行できます。

また、この用語は構文自体によって定義されているため、構文的に不適切な形式の「テンプレート定義」がないことにも注意してください。孤独+は、囲んでいるコンテキスト全体を無意味なトークンのスープにします。

最後になりましたが、委員会はこれらの「抜け穴」について知っていますが、私の知る限り、これを変更する過半数はありませんでした。

于 2012-07-21T11:08:50.597 に答える