テンプレートパラメータとして積分値を取って算術演算を実行できるので、boost :: mpl :: int_ <>と他の整数定数の背後にある動機は何ですか?このモチベーションはまだC++ 11にも当てはまりますか?Boost MPLに整数定数があるのはなぜですか?
答えて
あなたはテンプレートパラメータとしての整数値を取ることができますが、単一のテンプレートで種類と非型テンプレートパラメータの両方を取ることができません。長い話は短く、型テンプレートパラメータ以外のテンプレートパラメータをタイプとすると、MPL の無数のものに使用できます。例えば
、シーケンス内の同じタイプの種類とルックスで動作するメタ関数find
を検討してください。 型テンプレートパラメータ以外のテンプレートパラメータを使用する場合は、新しいアルゴリズムのオーバーロードを再実装する必要があります。find_c
タイプを手動で指定する必要があります。今度は、それが言語の残りの部分と同じように混在したタイプで動作したいと思っているか、またはタイプと以外のタイプを混在させたい場合、あなたは爆発的な「過負荷どこでも非型パラメータの型を指定する必要があるので、使用するのは難しいです。
この動機はまだC++ 11に適用されます。
この動機はまだC++に適用されますYと他のバージョン、我々は非型テンプレートパラメータからタイプテンプレートパラメータに変換することができますいくつかの新しいルールを持っていない限り。たとえば、5
を使用し、テンプレート要求でタイプを使用するたびにstd::integral_constant< int, 5 >
でインスタンス化します。
C++ y?私はそれがC++ 1yだと思った? –
tldr;値を型としてエンコーディングすると、単純な値よりはるかに多くの場所で使用できます。あなたは型をオーバーロードすることができます、あなたは値をオーバーロードすることはできません。
K-Balloの答えは素晴らしいです。
私は関連性があると思います。整数定数型は、テンプレート引数としてだけでなく、関数の引数や関数の戻り値の型としても役立ちます(私の例ではC++ 11の型を使用しますが、前者のBoostにも同じ引数が適用されます)。
template<typename R, typename... Args>
std::integral_constant<std::size_t, sizeof...(Args)>
arity(R (*)(Args...))
{ return {}; }
この関数は関数ポインタをとり、関数の引数の数を示す型を返します。 constexpr
の関数を使う前に、定数式で関数を呼び出す方法がなかったので、「この関数の型はいくつの引数を取るのですか? タイプを返し、そこから整数値を抽出する必要があります。
言語ではconstexpr
であっても(つまり、上記の関数はreturn sizeof...(Args);
であり、その整数値はコンパイル時に使用可能です)、積分定数型では依然として有効です。タグディスパッチ:
template<typename T>
void frobnicate(T&& t)
{
frob_impl(std::forward<T>(t), std::is_copy_constructible<T>{});
}
このfrob_impl
関数は、2番目の引数として渡されたinteger_constant<bool, b>
タイプに基づいて、オーバーロードすることができます。
template<typename T>
void frob_impl(T&& t, std::true_type)
{
// do something
}
template<typename T>
void frob_impl(T&& t, std::false_type)
{
// do something else
}
あなたはブールにテンプレートパラメータを作成することにより、類似した何かを試みることができる:
frob_impl<std::is_copy_constructible<T>::value>(std::forward<T>(t));
しかし、機能テンプレートを部分的に特殊化することはできません。frob_impl<true, T>
とfrob_impl<false, T>
は異なることを行います。 型のブール値定数のにオーバーロードすると、値の "コピー可能コンストラクタブル"特性とに基づいて簡単に異なることができます。はまだC++ 11では非常に便利です。
SFINAEを使用して形質を実装するために、定数が便利な別の場所があります。 C++ 03では、従来のアプローチでは、サイズが異なる2つのタイプ(例えば、int
と2つのint
を含む構造体)を返すオーバーロードされた関数を用意し、 "値"をsizeof
でテストしました。 C++ 11では、関数はより表現力豊かなtrue_type
とfalse_type
を返すことができます。 「このタイプにはfoo
というメンバーがありますか?正の結果を示す関数をtrue_type
とし、負の結果を返す関数をfalse_type
と返すようにすることができます。
コンパイル時「質問」の多くは、真/偽の答えを持っているので、私は2以上のものを持つことができる何かをテストしたい場合、標準ライブラリの実装者として、私は、true_type
とfalse_type
の非常に頻繁に利用します異なる結果integral_constant
の他のスペシャライゼーションを使用します。
'foo'と' bar'の何が問題なのですか? :P –
他のメタシンセティック変数にも愛が必要です! –
- 1. Boost MPL Types Vs Templates
- 2. なぜboost :: multi_arrayのConstMultiArrayConceptにNumDimsテンプレート引数があるのですか?
- 3. boost :: fusion :: tupleのmpl :: transform
- 4. Boost :: MPLの実際的な使用例?
- 5. なぜArray.Lengthは整数ではなく、整数ではない
- 6. なぜこの乗算に整数オーバーフローがありますか?
- 7. boost :: mpl :: for_each()でジェネリックラムダを呼び出す
- 8. 整数リテラルのマクロが整数変数で動作しないのはなぜですか?
- 9. なぜC言語のgetchar()関数が整数ですか?
- 10. なぜシンクセーフな整数ですか?
- 11. なぜcross_validation.train_test_splitの引数random_stateがブール値ではない整数
- 12. Boost Graph Libraryの `source()`はなぜグローバル関数ですか?
- 13. なぜ2つの正の整数の積は負の整数ですか?
- 14. 64ビットプラットフォームでsize_typeが32ビット整数になるのはなぜですか?
- 15. mpl :: vectorを使用してboost :: variant型を定義する
- 16. 簡単な例のためにmplの数を増やす
- 17. boost :: mpl for_eachから抜け出す方法はありますか?
- 18. 整数がYYYYMMDDの形式のCDate(整数)が動作しないのはなぜですか?
- 19. mplスタイルcopy_if可変テンプレートベクトルのメタ関数
- 20. 整数を入力すると、これは整数ではないのはなぜですか? (Python)
- 21. Ada:整数をコンソールに印刷するときに大きなスペースがあるのはなぜですか?
- 22. 整数除算の結果のクラスが整数でないのはなぜですか?
- 23. linuxに複数のfcntl.hがあるのはなぜですか?
- 24. C++で整数のベクトルを整数の2次元ベクトルにプッシュできないのはなぜですか?
- 25. なぜ整数が等しくないのですか?
- 26. なぜ整数== nullがC#の有効なブール式ですか?
- 27. なぜポートは整数ではなく文字列ですか?
- 28. 整数型の最大値の定数はありますか?
- 29. boost :: asio :: io_service - なぜポスト関数を使うのですか?
- 30. なぜ私のブール値が整数を返すのですか?
Boost MPLの主著者の著書「C++ Template Metaprogramming」を読んで、これらのすべての背後にある動機について説明します。これはC++ 11でのみ有効ではなく、[std :: integral_constant](http://en.cppreference.com/w/cpp/types/integral_constant)でC++ 11で標準化されています。 –