I l@ve RuBoard |
![]() ![]() |
2.6 Type SelectionSometimes generic code needs to select one type or another, depending on a Boolean constant. In the NiftyContainer example discussed in Section 2.4, you might want to use an std::vector as your back-end storage. Obviously, you cannot store polymorphic types by value, so you must store pointers. On the other hand, you might want to store nonpolymorphic types by value, because this is more efficient. In your class template, template <typename T, bool isPolymorphic> class NiftyContainer { ... }; you need to store either a vector<T*> (if isPolymorphic is true) or a vector<T> (if isPolymorphic is false). In essence, you need a typedef ValueType that is either T* or T, depending on the value of isPolymorphic. You can use a traits class template (Alexandrescu 2000a), as follows. template <typename T, bool isPolymorphic> struct NiftyContainerValueTraits { typedef T* ValueType; }; template <typename T> struct NiftyContainerValueTraits<T, false> { typedef T ValueType; }; template <typename T, bool isPolymorphic> class NiftyContainer { ... typedef NiftyContainerValueTraits<T, isPolymorphic> Traits; typedef typename Traits::ValueType ValueType; }; This way of doing things is unnecessarily clumsy. Moreover, it doesn't scale: For each type selection, you must define a new traits class template. The library class template Select provided by Loki makes type selection available right on the spot. Its definition uses partial template specialization. template <bool flag, typename T, typename U> struct Select { typedef T Result; }; template <typename T, typename U> struct Select<false, T, U> { typedef U Result; }; Here's how it works. If flag evaluates to true, the compiler uses the first (generic) definition and therefore Result evaluates to T. If flag is false, then the specialization enters into action and therefore Result evaluates to U. Now you can define NiftyContainer::ValueType much more easily. template <typename T, bool isPolymorphic> class NiftyContainer { ... typedef typename Select<isPolymorphic, T*, T>::Result ValueType; ... }; ![]() |
I l@ve RuBoard |
![]() ![]() |