質問

C ++で見たメタプログラミングの最もクールな例は何ですか?
C ++で見たメタプログラミングの実用的な用途は何ですか?

役に立ちましたか?

解決

個人的には、 Boost.Spirit は、メタプログラミングの非常に素晴らしい例です。 C ++構文を使用して文法を表現できる完全なパーサージェネレーターです。

他のヒント

メタプログラミングの最も実用的な使用法は、ランタイムエラーをコンパイル時エラーに変換することです。

例:インターフェースIFooを呼び出します。私のプログラムの1つは、IFoo(非常に複雑な継承階層)への複数のパスを持つCOMオブジェクトを扱いました。残念ながら、基礎となるCOMオブジェクトの実装は、IFooへの複数のパスがあることを認識していませんでした。彼らは、それが常に一番左であると仮定しました。そのため、コード内では次のパターンが非常に一般的でした

   void SomeMethod(IFoo* pFoo) {
        CFooImpl *p = (CFooImpl)pFoo;
   }

2番目のIFooは、結果として<!> quot; p <!> quot;を引き起こしました。完全に無効なポインタ(多重継承は危険です)。

長期的な解決策は、COMオブジェクトの所有者にこの問題を修正してもらうことでした。短期的には、常に正しいIFooを返すようにする必要がありました。 QIを使用し、IFooへの暗黙のキャストを回避することにより、適切なIFooが存在することを保証できます。そこで、新しいCComPtr <!> lt; <!> gt;を作成しました。実装し、equalメソッドに次のオーバーライドを追加しました。

template <typename T>
CComPtr<T>& operator=(const T* pT)  { 
// CComPTr Assign logic
}
template <>
CComPtr<IFoo> operator=<IFoo>(const IFoo* pT) {
  COMPILE_ERROR();
}

これにより、私が暗黙のうちにIFooにキャストしたすべての場所がすぐに明らかになりました。

実用的な使用法ではありません(コンパイラテストを除く)が、 metatrace はウィットスタイル(つまり再帰的)です。および決定論的)コンパイル時のような画像を生成するレイトレーサー:

メタトレースの例

コードのより複雑な部分が fixp.hh 。Heronを使用した固定小数点sqrtの実装メソッド、または sphere.hh (ray / sphere-intersectionを表示)計算。

Blitz ++ は、テンプレートを使用していくつかの印象的なことを行います(たとえば、単一の読み取り可能なコード行を多次元配列上のループのセットになり、最適な走査順序に合わせて自動的に最適化されます。

クールなメタプログラミングの例:コンパイラーをtrickして素数のリストを計算させます。あまり実用的ではありませんが、印象的です。

実用的な用途の1つは、コンパイル時のアサートステートメントです。つまり、ブール条件が成立しない場合にコンパイルエラーが発生します。

Boost.Lambda、Boost.Function、Boost.Bind、およびそれらすべてがシームレスに連携する方法を言わなければなりません。彼らは本当に洗練されたインターフェースを提供し、実際にそれのために構築されていない言語での関数型プログラミングを可能な限り簡単にします。

luabindはかなりクールで実用的な例であり、C ++クラスをluaにバインドするための非常に優れたバインディングdsl

BOOST_FOREACH

静的アサーション(boostsバージョンこちら

(注:C ++ 11では、範囲ベースのforループと静的アサーションの組み込みサポートが導入されています)

ずっと前に質問しました: C ++クラスの実行時知識とStackOverflowユーザーから返された答え<!> quot; Denice <!> quot; WebサイトへのURL ミートスペース:C ++ランタイムクラス登録

これは、テンプレートを使用して、すべて基本クラスから派生したオブジェクトをインスタンス化するための本当にクールな方法だと思います。したがって、10個のC ++ファイルがある場合、すべての下部にAUTO_REGISTER_BASE()すべてが行われ、リンクされます。それを作成したクラス/ファイルのみが登録されるため、実行時に使用可能なさまざまなクラスを切り替えることができます。使用できないクラスは登録されないため、誤って呼び出すことはできません。

イベント通知を行うOSに依存するさまざまな方法があります(select()、kqueue()、/ dev / epoll、Solarisには独自のpoll()があり、すべてのクラスを持つ方法が必要でしたファイルはディレクトリに存在しますが、Makefileが実行されたOSに応じて、特定のファイルのみをコンパイルします。実行時にどのライブラリが利用可能かを知り、ライブラリを使用するプログラマーが好みを選択する方法が必要でしたが、プラットフォームにとって最も論理的な意味のあるもの(それぞれがウェイトが割り当てられています)。

上記のコードは、いくつかの大きな変更を加えてこの目標を達成するのに役立ちましたが、それでもなお助けになりました!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top