1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
Another use of values buried inside templates is to `templatize' simple scalar
tt(int) values. This is useful in situations where a scalar value (often a
tt(bool) value) is available to select a specialization but a type is required
to base the selection on. This situation is shortly encountered (section
ref(ALTERNATIVES)).
Templatizing
hi(template: embedding integral values)
integral values is based on the fact that a
hi(class template: defining a type)
class template together with its template arguments defines a type. E.g.,
tt(vector<int>) and tt(vector<double>) are different types.
Turning integral values into templates is easily done. Define a template (it
does not have to have any content at all) and store the integral value in an
tt(enum):
verb( template <int x>
struct IntType
{
enum { value = x };
};)
As tt(IntType) does not have any members the `tt(class IntType)' can be
defined as `tt(struct IntType)', saving us from having to type tt(public:).
Defining the tt(enum) value `tt(value)' allows us to retrieve the value
used at the instantiation at no cost in storage. Enum values are neither
variables nor data members and thus have no address. They are mere values.
It's easy to use the tt(struct IntType). An anonymous or named
object can be defined by specifying a value for its tt(int) non-type
parameter. Example:
verb( int main()
{
IntType<1> it;
cout << "IntType<1> objects have value: " << it.value << "\n" <<
"IntType<2> objects are of a different type "
"and have values " << IntType<2>().value << '\n';
})
Actually, neither the named object nor the anonymous object is
hi(class template: values without objects)
required. As the tt(enum) is defined as a plain value, associated with the
tt(struct IntType) we merely have to specify the specific tt(int) for which
the tt(struct IntType) is defined to retrieve its `tt(value)', like this:
verb( int main()
{
cout << "IntType<100>, no object, defines `value': " <<
IntType<100>::value << "\n";
})
|