# Type SelectionEdit

### IntentEdit

Select a type at compile-time based on a compile-time boolean value or a predicate.

### Also Known AsEdit

### MotivationEdit

Ability to take decisions based on the information known at compile-time is a powerful meta-programming tool. One of the possible decisions to be made at compile-time is deciding a type i.e., the choice of the type may vary depending upon the result of a predicate.

For example, consider a *Queue* abstract data-type (ADT) implemented as a class template that holds a static array of Ts and the maximum capacity of the Queue is passed as a template parameter. The Queue class also needs to store the number of elements present in it, starting from zero. A possible optimization for such a queue class could be to use different types to store the size. For instance, when Queue's maximum capacity is less than 256, *unsigned char* can be used and if the capacity is less than 65,536, *unsigned short* can be used to store the size. For larger queues, *unsigned integer* is used. Type selection idiom can be used to implement such compile-time decision making.

### Solution and Sample CodeEdit

A simple way of implementing the type selection idiom is the *IF* template. IF template takes three parameters. The first parameter is a compile-time boolean condition. If the boolean condition evaluates to *true* the 2nd type passed to the IF template is chosen otherwise third. Type selection idiom consists of a primary template and a partial specialization as shown below.

template <bool, class L, class R> struct IF // primary template { typedef R type; }; template <class L, class R> struct IF<true, L, R> // partial specialization { typedef L type; }; IF<false, int, long>::type i; // is equivalent to long i; IF<true, int, long>::type i; // is equivalent to int i;

We now use the type selection idiom to implement the Queue size optimization mentioned above.

template <class T, unsigned int CAPACITY> class Queue { T array[CAPACITY]; typename IF<(CAPACITY <= 256), unsigned char, typename IF<(CAPACITY <= 65536), unsigned short, unsigned int >::type >::type size; // ... };

The Queue class template declares an array or Ts. The type of the *size* data member depends on the result of two comparisons performed using the *IF* template. Note that these comparisons are not performed at run-time but at compile-time.

### Known UsesEdit

- Boost.MPL Library