Boost :: MPLの使用法(ラムダを除く)の実際の例を共有して、その目的と実際の使用法の分野をよりよく理解できるようにしてください。MPLドキュメントのチュートリアルには、次元分析の例がありますが、それはそのような学術的な例であるため、Boost::MPLの感覚とそれを効果的に使用できる時期を私に与えていない可能性があります。
8 に答える
実際、Boost.Preprocessorと同様に、Boost.MPLは実際にはビルディングブロックです。
多くのBoostライブラリは、これら2つのライブラリに基づいて構築されているため、ほとんどの場合、他のライブラリを介して使用します。
例えば:
- Boost.Fusion(コンパイル時と実行時のレルム間のギャップを越える)
- Boost.MultiIndex(より簡単なインターフェースのために)
- Boost.Unit(次元分析用)
- Boost.Variantもそれに依存していると思います
あなたはすでにそれを知らないうちに使うかもしれません:)
Boost.Mpl を使用してバリアントのようなクラスを生成しました。
たとえば、次のような MPL タイプ リストがあるとします。
typedef boost::mpl::set<Foo, Bar, Baz> type_set;
次に、 を使用boost::mpl::fold
して、互いに派生したクラスのチェーンを構築し、それぞれがstd::unordered_set
型セット内のいずれかの型を追加します。unordered_set<Foo>
最終結果は、 、 、unordered_set<Bar>
およびを含むクラスunordered_set<Baz>
です。
また、クラスは a で指定されているため、これらの型を繰り返し処理して、すべての を比較boost::mpl::set
する an などの他の関数も自動的に生成できます。operator==
unordered_set
Boost.Units と呼ばれる、より拡張された次元分析ライブラリを使用します。
コンパイル時のリフレクション ライブラリを開発し、そのライブラリを使用して、渡されたコンパイル時のリフレクション型にランタイム リフレクションを提供するジェネリック クラスを作成しました。そのサポートを使用して、プロパティを編集する UI コンポーネントを自動的に生成しました。そのような反映されたタイプの。
また、アプリケーション内でのイベントの配布にとっても重要です。たとえば、誰かがシステムに入れたいユニットを変更した場合、コードは MPL を使用してそれらのタイプを分析し、何かが追加されたことを知っているだけなので、特定のデバイスに新しいアイテムが追加されたことをそのシステムに教える必要はありません。そしてそれを変更します。
メタプログラミング手法を使用して、システムによって削除された型の安全性を取り戻し、任意の機能エンティティに接続できるものに Qt シグナルをラップしました。
しかし、実を言うと、ソートなどの標準アルゴリズムを使用したときに、実用的なメタプログラミング手法をすでに使用していることはほぼ確実です。ソート アルゴリズムの適切な実装では、あまり進化していない形式のメタプログラミングを使用して、渡されたイテレータを分析し、タグ ディスパッチを使用して、それらのイテレータの機能を十分に活用できるソート アルゴリズムを開始します。
率直に言って、メタプログラミングを行っていないのであれば、C++ の機能を利用していないということであり、別のものを使用している可能性もあります。
私はstat_logライブラリで boost::mpl (および boost::fusion) を広範囲に使用しています。このライブラリを使用すると、ユーザーは統計タグとログ タグの階層、およびそれらに関連付けられた動作、つまりタグごとの統計タイプ (ヒストグラム、カウンターなど) を指定できます。
私はメタプログラミングに大きく依存して、ユーザーが行う正しいことを行います。
stat_log::writeStat<IP_PKTS_RCVD>(450);
たとえば、ユーザーが型特性を定義した場合:
template <>
struct stat_tag_to_type<IP_PKTS_RCVD>
{
using type = Accumulator<
stat_log::HistogramCount<
int,
1, //start bin
1500, //stop bin
10 //num_bits
>
>;
};
上記の「writeStat」呼び出しは、(コンパイル時に) ヒストグラム統計にプロキシします。この設計手法の強力な側面は、「writeStat」呼び出しサイトが、選択された特定の統計とまったく結び付いていないことです。
また、実際に統計を表示するために、豊富な MPL と boost::fusion を使用します。あなたの質問に応じて、boost::mpl の最高濃度については次のファイルを参照してください。
https://github.com/rjmccabe3701/stat_log/blob/master/include/stat_log/util/stat_log_impl.h https://github.com/rjmccabe3701/stat_log/blob/master/include/stat_log/util/tag_commander.h https://github.com/rjmccabe3701/stat_log/blob/master/include/stat_log/stat_log.h
特に stat_log_impl.h の気の利いたテンプレート メタ「関数」:
//This template is used in conjunction with an MPL algorithm
// with the same semantics as mpl::find_if.
//BoolFunc is the "condition" metafunction.
//StatTagFunc is a metafunction that transforms the given
// stat_tag into something the algorithm requires.
// For example the "Identity" metafunction would work here.
//StatTagArgs is extra arguments to the BoolFunc
template <template<typename...> class BoolFunc,
template<typename...> class StatTagFunc,
class... StatTagArgs>
struct tag_node_query
{
template<typename TheTagNode>
struct apply
{
using stat_tag = typename TheTagNode::tag;
using type = std::integral_constant
<
bool,
BoolFunc<
typename StatTagFunc<stat_tag>::type,
StatTagArgs...
>::value
>;
};
};
Matthieuの答えに加えて、 Boost.PythonとLuabindの両方で非常に広く使用されています。
私がした面白いこと: https://github.com/edubois/static-factorial/blob/master/main.cpp
これは、boost::mpl のごく一部を使用して、factorial<8>() の値を静的に計算します...
これは、主なアイデアを理解するのに役立ちます。