C ++:C ++機能ではなくコンパイラAPIを使用したメタプログラミング
これはSOの質問として始まりましたが、それはかなり型破りであり、Webサイト上の実際の説明に基づくと、質問には多くの概念的な重みがあるため、programmers.seに適している可能性があることに気付きました。 私はclang LibToolingを学習してきましたが、これは非常に強力なツールであり、コードの「ぎこちない」全体をフレンドリーな方法で、つまりセマンティックな方法で、推測することなく公開できます。clangがコードをコンパイルできる場合、clangはそのコード内のすべての単一文字のセマンティクスについて確実です。 ここで、少し前に戻ります。 C ++テンプレートのメタプログラミングに従事する場合(特に、恐ろしいマクロではあるが、テンプレートを超えて賢い領域に冒険する場合)には、多くの実用的な問題が発生します。正直なところ、私も含めて多くのプログラマーにとって、テンプレートの通常の使用法の多くは、やや恐ろしいものです。 良い例は、コンパイル時の文字列だと思います。これは、1年以上前の質問ですが、現時点でのC ++では、これが単なる人間にとって容易ではないことは明らかです。これらのオプションを見るだけでは吐き気を誘発するのに十分ではありませんが、それでも、私が自分のソフトウェアで使用している空想のアプリケーションに適合する魔法の、最大限に効率的なマシンコードを生成できるかどうか自信がありません。 正直言って、皆さん、文字列はかなりシンプルで基本的なものです。私たちの中には、特定の文字列が単純な方法でコーディングする場合よりも大幅に「組み込まれた」マシンコードを生成する便利な方法を求めているだけです。私たちのC ++コードで。 clangとLibToolingを入力します。これにより、ソースコードの抽象構文ツリー(AST)が公開され、シンプルなカスタムC ++アプリケーションRewriterが、ASTのすべての豊富なセマンティックオブジェクト指向モデルと一緒に、生のソースコードを(確実に)正しく正確に操作できるようになります。それは多くのものを扱います。マクロ展開について知っているので、それらのチェーンをたどることができます。はい、私はソースからソースへのコード変換または変換について話しています。 ここでの私の基本的な論点は、clangにより、C ++ソフトウェアの理想的なカスタムプリプロセッサステージとして機能する実行可能ファイルを作成できるようになり、これらのメタプログラミングステージをC ++で実装できるということです。このステージは、有効なC ++コードである入力を受け取り、より有効なC ++コードを出力として生成する必要があるという事実に制約されます。さらに、ビルドシステムが適用するその他の制約。 結局のところ、clangはコンパイラのフロントエンドであり、APIを使って独創的であるため、入力は少なくとも有効なC ++コードに非常に近い必要があります。使用する新しい構文を定義できるようにする準備があるかどうかはわかりませんが、これを正しく解析してclangプロジェクトに追加する方法を開発する必要があることは明らかです。これ以上期待することは、clangプロジェクトに範囲外の何かを含めることです。 問題ない。一部の何もしないマクロ関数がこのタスクを処理できると思います。 私が説明していることを確認する別の方法は、言語自体で利用できるより限定されたツールを使用して実装する代わりに、ソースコードのAST(clangとそのAPIのおかげ)を操作することにより、ランタイムC ++を使用してメタプログラミング構成を実装することです。これには、明らかなコンパイルパフォーマンスの利点もあります(テンプレートが多いヘッダーでは、使用頻度に比例してコンパイルが遅くなります。コンパイルされたものの多くは、慎重に照合され、リンカーによって破棄されます)。 ただし、これには、ビルドプロセスに追加の手順を1つまたは2つ追加するコストと、ツールの一部として(確かに)多少冗長なソフトウェア(ただし、少なくとも単純なランタイムC ++)を記述する必要があります。 。 それは全体像ではありません。コア言語の機能では非常に困難または不可能であるコードを生成することで、はるかに大きな機能空間を確保できると確信しています。C ++ではテンプレート、マクロ、またはその両方のクレイジーな組み合わせを記述できますが、clangツールでは、セマンティックコンテンツへのフルアクセスを持ちながら、実行時に C ++で実現できる方法でクラスと関数を変更できます。テンプレートとマクロ、その他すべてに加えて。 それで、なぜ誰もがまだこれをしていないのかと思っています。clangのこの機能は非常に新しく、clangのASTの巨大なクラス階層に誰も精通していないのでしょうか?それはそれではありえない。 おそらく、私はこれの難しさを少し過小評価しているだけですが、clangツールを使用して「コンパイル時の文字列操作」を行うことは、犯罪的にほぼ単純です。冗長ですが、非常に単純です。必要なのは、実際の実際のstd::string操作にマップする一連のno-opマクロ関数だけです。clangプラグインは、関連するすべてのno-opマクロ呼び出しをフェッチしてこれを実装し、文字列を使用して操作を実行します。このツールは、ビルドプロセスの一部として挿入されます。ビルド中に、これらのno-opマクロ関数呼び出しは自動的にその結果に評価され、プログラム内の単純な古いコンパイル時文字列として挿入されます。その後、プログラムは通常どおりコンパイルできます。実際、結果として得られるこのプログラムは、結果としてはるかに移植性が高くなり、C ++ 11をサポートする豪華な新しいコンパイラーを必要としません。