I l@ve RuBoard |
![]() ![]() |
3.6 Indexed AccessHaving access by index to the elements of a typelist would certainly be a desirable feature. It would linearize typelist access, making it easier to manipulate typelists comfortably. Of course, as with all the entities we manipulate in our static world, the index must be a compile-time value. The declaration of a template for an indexed operation would look like this: template <class TList, unsigned int index> struct TypeAt; Let's define the algorithm. Keep in mind that we cannot use mutable, modifiable values.
Here's the incarnation of the TypeAt algorithm: template <class Head, class Tail> struct TypeAt<Typelist<Head, Tail>, 0> { typedef Head Result; }; template <class Head, class Tail, unsigned int i> struct TypeAt<Typelist<Head, Tail>, i> { typedef typename TypeAt<Tail, i - 1>::Result Result; }; If you try an out-of-bound access, the compiler will complain that there's no specialization defined for TypeAt<NullType, x>, where x is the amount by which you bypass the list size. This message could be a bit more informative, but it's not bad, either. Loki (file Typelist.h) also defines a variant of TypeAt, called TypeAtNonStrict. TypeAtNonStrict implements the same functionality as TypeAt, with the difference that an out-of-bound access is more forgiving, yielding a user-chosen default type as the result instead of a compile-time error. The generalized callback implementation described in Chapter 5 uses TypeAt-NonStrict. Indexed access in typelists takes linear time according to the size of the typelist. For lists of values, this method is inefficient (for this reason, std::list does not define an operator[]). However, in the case of typelists, the time is consumed during compilation, and compile time is in a sense "free."[2]
|
I l@ve RuBoard |
![]() ![]() |