「More C++ Idioms/整数から型(Int-To-Type)」の版間の差分

削除された内容 追加された内容
Yak! (トーク | 投稿記録)
現内容を翻訳
1 行
=<center>整数から型(Int-To-Type)</center>=
=== Intent意図 ===
* コンパイル時に整数定数を型として扱う。
* To treat an integral constant as a type at compile-time.
* 整数定数値に基づいて静的な呼び分け(dispatch)を実現する。
* To achieve static call dispatch based on constant integral values.
 
=== Also Known As別名 ===
整数定数ラッパ(Integral constant wrappers)
 
=== Motivation動機 ===
C++ における関数の多重定義は型が異なることに基づいており、コンパイル時整数定数を関数の多重定義の解決に利用することができない。整数定数に基づいて静的な呼び分け(dipatch)を実現する方法が少なくとも 2 つある。一つは [[More C++ Idioms/enable-if|enable-if]] イディオムであり、もう一つが以下で記述する整数から型(Int-To-Type)イディオムである。
Function overloading in C++ is based on different types, which prevents compile-time integral constants taking part into function overload resolution. There are at least two different mechanisms to perform static dispatching based on integral constants. First is [[More C++ Idioms/enable-if|enable-if]] idiom and the other one is the int-to-type idiom described below.
 
=== Solution and Sample Code解法とサンプルコード ===
AAndrei simpleAlexandrescu template, initially described inによって [http://www.ddj.com/cpp/184403750 Dr. Dobb's Journal] by Andrei Alexandrescu provides a solution to this idiom.で初めて記述された単純なテンプレートがこのイディオムの解法を提供する。
 
<source lang="cpp">
21 行
</source>
 
上記テンプレートはテンプレートのインスタンス化を用いることで異なる値に対して異なる型を作成する。例えば、''Int2Type<5>'' は ''Int2Type<10>'' と異なる型である。さらに、整数のパラメータは関連づけられた定数 ''value'' に保存されている。整数定数それぞれが異なる型を生み出すため、この単純なテンプレートを以下のように整数定数に基づく静的な呼び分け(dispatch)に用いることができる。
The above template creates different types for different integer values used to instantiate the template. For example, ''Int2Type<5>'' is a different type from ''Int2Type<10>''. Moreover, the integral parameter is saved in the associated constant ''value''. As each integral constant results in a different type, this simple template can be used for static dispatching based on integral constants as shown below.
 
''Array'' クラスを固定長の配列をカプセル化するクラスで TR1 にある標準 array クラスによく似たクラスとする。実際には、我々の Array クラスは標準の TR1 array クラスの派生クラスとして実装されており違いは ''sort'' 関数のみである。
Consider an ''Array'' class that encapsulates a fixed size array very similar to that of the standard array class from TR1. In fact, our Array class is implemented as a derived class of the standard TR1 array class with the only difference of a ''sort'' function.
 
性能に対する最適化を達成するため、配列のサイズによってコンパイル時に sort 関数の呼び分け(dispatch)をする。例えば、配列のサイズが 0 あるいは 1 の場合はソートは何もしない。同様に、サイズが 50 より小さな配列は挿入ソートアルゴリズムによってソートされ、より大きな配列はクイックソートアルゴリズムによってソートされる。なぜなら小さなデータサイズに対しては、挿入ソートアルゴリズムの方がクイックソートアルゴリズムよりも効率的である場合が多いからである。このソートアルゴリズムの選択は実行時の ''if'' によって自明に実行可能である点に注意しよう。しかし、以下のように整数から型(Int-To-Type) イディオムによってコンパイル時に同様の効果を得ることができる。
We intend to dispatch sort function at compile-time based on the size of the array to achieve some performance optimizations. For example, sorting an array of size zero or one should be a no-op. Similarly, arrays smaller than size 50 should be sorted using the insertion-sort algorithm whereas as larger arrays should be sorted using the quick-sort algorithm because insertion-sort algorithm is often more efficient than quick-sort algorithm for small data size. Note that, this selection of the sorting algorithm can be trivially done using run-time ''if'' condition. However, int-to-type idiom is used to achieve the same effect at compile-time as shown below.
 
<source lang="cpp">
41 行
{
enum AlgoType { NOOP, INSERTION_SORT, QUICK_SORT };
static const int algo = (N==0) ? NOOP :
(N==1) ? NOOP :
(N<50) ? INSERTION_SORT : QUICK_SORT;
void sort (Int2Type<NOOP>) { std::cout << "NOOP何もしない\n"; }
void sort (Int2Type<INSERTION_SORT>) { std::cout << "INSERTION_SORT挿入ソート\n"; }
void sort (Int2Type<QUICK_SORT>) { std::cout << "QUICK_SORTクイックソート\n"; }
public:
void sort()
56 行
{
Array<int, 1> a;
a.sort(); // No-op!何もしない!
Array<int, 400> b;
b.sort(); // Quick sortクイックソート
}
</source>
 
利便性を向上するために、''Int2Type'' にいくつか関連する型と定数を定義することができる。例えば、列挙型 ''value'' を型に関連づけられた整数定数を取得するために利用できる。また、''Int2Type<7>::next'' が ''Int2Type<9>::previous'' と同じ型になるような ''next'' と ''previous'' のような他の typedef を他の型を ''順番に'' 探すために利用することができる。
Few more associated types and constants can be defined with ''Int2Type'' template to increase its usability. For example, enumeration ''value'' is used to retrieve the integer constant associated with the type. Finally, other typedefs such as, ''next'' and ''previous'' are used to find other types ''in order'' such that ''Int2Type<7>::next'' is the same type as ''Int2Type<9>::previous''.
 
<source lang="cpp">
76 行
</source>
 
=== Known Uses既知の利用 ===
* Boost.MPL 中の [http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/refmanual/integral-constant.html Integral constant wrappers (bool_, int_, long_)] in Boost.MPL
* [http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/tutorial/representing-dimensions.html Dimensional Analysis]
 
=== Related Idioms関連するイディオム ===
* [[More C++ Idioms/enable-if|enable-if]]
* [[More C++ Idioms/型生成器(Type Generator)|型生成器(Type Generator)]]
 
=== References ===
[1] [http://www.ddj.com/cpp/184403750 Generic<Programming>: Mappings between Types and Values] -- Andrei Alexandrescu
 
[[Category:{{BASEPAGENAME}}|{{SUBPAGENAME}}]]
<noinclude>
[[en:More C++ Idioms/Int-To-Type]]
</noinclude>
[[Category:{{BASEPAGENAME}}|{{SUBPAGENAME}}せいすうからかた]]