tags:

views:

62

answers:

1
+2  Q: 

Detecting a type

Ignore this question, just found a mistake in my code, flag to delete it

This is from "Templates - the complete guide" ch. 19.2
Compound types are types constructed from other types. Simple compound types include plain types, pointer types, reference types, and even array types. They are constructed from a single base type. Class types and function types are also compound types, but their composition can involve multiple types (for parameters or members). Simple compound types can be classified using partial specialization. We start with a generic definition of a traits class describing compound types other than class types and enumeration types (the latter are treated separately):

// types/type2.hpp 
template<typename T> 
class CompoundT {           // primary template 
  public: 
    enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, 
           IsFuncT = 0, IsPtrMemT = 0 }; 
    typedef T BaseT; //This suppose to be different
    typedef T BottomT; //to this! But is typedef'ed in the same way! FFS!
    typedef CompoundT<void> ClassT; 
}; 

The member type BaseT is a synonym for the immediate type on which the template parameter type T builds. BottomT, on the other hand, refers to the ultimate nonpointer, nonreference, and nonarray type on which T is built. For example, if T is int*, then BaseT would be int, and BottomT would be int.
Did that, tried that and guess what do not work. For int** BaseT is int** and for BottomT the same. To me it's obvious that there is a mistake in the book. How on earth identically typedef'ed type can be different? For me it cannot. I would like to know what should be there (in the class decl.) to make it work.
Thank you.

A: 

Well where are the specializations? Yeah, this is the primary template which should be instantiated for non-compound types, if I understand correctly. And naturally, with this template alone, nothing can be done. On the other hand, let's consider a specialization for pointers (for arrays, etc., it's similar)

template<typename T> 
class CompoundT<T*> {           // specialization for pointers
  public: 
    enum { IsPtrT = 1, IsRefT = 0, IsArrayT = 0, 
           IsFuncT = 0, IsPtrMemT = 0 }; 
    typedef T BaseT;
    typedef typename CompoundT<BaseT>::BottomT BottomT; 
    typedef CompoundT<void> ClassT; //not sure what this is for
}; 

now, for int** baseT will be int* and BottomT will be int. HTH

Armen Tsirunyan