C++テンプレートは、長くて読めないエラーメッセージを生成することで有名です。 C++のテンプレートエラーメッセージがなぜそれほどひどいのか、という一般的な考えがあります。基本的に、問題は、コンパイラーがテンプレート内の特定のタイプでサポートされていない構文を検出するまでエラーがトリガーされないことです。例えば:
_template <class T>
void dosomething(T& x) { x += 5; }
_
T
が_+=
_演算子をサポートしていない場合、コンパイラはエラーメッセージを生成します。また、これがライブラリ内のどこかで発生した場合、エラーメッセージは数千行になることがあります。
しかし、C++テンプレートは基本的に、コンパイル時のダックタイピングのメカニズムにすぎません。 C++テンプレートエラーは、概念的には、Pythonなどの動的言語で発生する可能性があるランタイム型エラーに非常に似ています。たとえば、次のPythonコードを考えてみます。
_def dosomething(x):
x.foo()
_
ここで、x
にfoo()
メソッドがない場合、Pythonインタープリターが例外をスローし、スタックトレースとかなり明確なエラーを表示します問題を示すメッセージ。インタプリタがライブラリ関数の奥深くに入るまでエラーがトリガーされない場合でも、ランタイムエラーメッセージは、通常のC++コンパイラによって吐き出された読み取り不可能な嘔吐ほど悪くはありません。 C++コンパイラーは何が問題であったかについてより明確ではないのですか?一部のC++テンプレートエラーメッセージが文字通りコンソールウィンドウを5秒以上スクロールさせるのはなぜですか?
テンプレートのエラーメッセージは悪名高いかもしれませんが、必ずしも長くて読めないわけではありません。この場合、エラーメッセージ全体(gccから)は次のとおりです。
test.cpp: In function ‘void dosomething(T&) [with T = X]’:
test.cpp:11: instantiated from here
test.cpp:6: error: no match for ‘operator+=’ in ‘x += 5’
Pythonの例のように、テンプレートのインスタンス化ポイントの「スタックトレース」と、問題を示す明確なエラーメッセージが表示されます。
時には、さまざまな理由により、テンプレート関連のエラーメッセージがはるかに長くなることがあります。
Python=との主な違いは静的型システムであり、エラーメッセージに(場合によっては長い)型名を含める必要があります。これらがないと、診断が非常に困難になることがあります- why過負荷の解決に失敗しました。これらを使用すると、問題はどこにあるかを推測するのではなく、どこにあるかを示す象形文字を解読することです。
また、実行時にチェックすると、プログラムは最初に発生したエラーで停止し、単一のメッセージのみを表示します。コンパイラーは、発生するすべてのエラーを、あきらめるまで表示します。少なくともC++では、ファイル内の最初のエラーで停止しないでください。これは、後のエラーの結果である可能性があるためです。
明らかな理由のいくつかは次のとおりです。
それは網羅的ではありませんが、あなたは一般的な考えを理解します。簡単ではないにしても、ほとんどは治ります。何年もの間、私は人々に定期的に使用するためにコモーC++のコピーを入手するように言ってきました。たぶん、コンパイラーの代金を払うために、1つのエラーメッセージから1回は十分に節約できました。現在、Clangは同じ点に到達しています(そして、それはさらに安価です)。
最後に、冗談のように聞こえるかもしれませんが、実際はそうではない一般的な所見をまとめます。ほとんどの場合、ソースコードをエラーメッセージに変換するコンパイラの実際の仕事は正直なところisです。ベンダーがその仕事をもう少しよくすることに集中している時期です-私がコンパイラーを書いたとき、私はそれを二次的(せいぜい)として扱う傾向が強く、場合によってはそれをほとんど無視したことを公然と認めます完全に。
簡単な答えは、Pythonはそのように機能するように設計されているためですが、テンプレートに関連する多くのものが偶然に生じたものです。それ自体がチューリング完全なシステムになることは意図されていませんでした。たとえば、システムが意図的に計画されて、何が起こるかについて推論できない場合works何かがうまくいかなかったときに何が起こるかについて、慎重で思慮深い計画を誰もが期待する必要があるのはなぜですか。
また、あなたが指摘したように、Pythonインタプリタは、Pythonコードを解釈しているため、スタックトレースを表示することにより、はるかに簡単になります。C++の場合コンパイラーがテンプレートエラーにヒットし、スタックトレースを提供します。これは、「テンプレートの嘔吐」と同じくらい役に立ちませんよね。