Previous section   Next section

Imperfect C++ Practical Solutions for Real-Life Programming
By Matthew Wilson
Table of Contents
Part Three.  Language Concerns


Chapter 18. Typedefs

The typedef specifier in C and C++ provides a new name for a given type. Two classic uses in C are in removing confusion when using function pointers and reducing typing effort when using structures. Consider the code without typedefs in Listing 18.1.

Listing 18.1.


// Info.h


struct Info


{};


int process(int (*)(struct Info*, int*), int*);





// client_code.cpp


int process_forwards(struct Info*, int);


int process_backwards(struct Info*, int);





int main()


{


  struct Info info;


  int (*pfn[10])(struct Info*, int);


  . . .


  for(i = 0; . . .; ++i)


  {


    pfn[i] = . . .



Contrast that with the code in Listing 18.2 that uses structure and function pointer typedefs.

Listing 18.2.


// Info.h


typedef struct Info {} Info_t;              // struct typedef


typedef int (*processor_t)(Info_t*, int*);  // fn ptr typedef


int process(processor_t , int*);





// client_code.cpp


int process_forwards(Info_t*, int);


int process_backwards(Info_t*, int);





int main()


{


  Info_t      info;


  processor_t pfn[10];


  . . .


  for(i = 0; . . .; ++i)


  {


    pfn[i] = . . .



I hope you'll agree that the latter form is far more readable. It is also legal (C++-98: 7.1.3,2) to redefine the name of any type (within the same scope) to the type to which it already refers. This is pretty pointless for many types—for example, typedef int SInt; typedef SInt SInt;—but it is very useful for removing the need to type struct or to remember the association between a given structure typedef and the actual structure for which it acts as a synonym:



typedef struct Info {} Info; // synonym of itself


. . .


int main()


{


  Info        info;


  . . .



In fact, C++ differs from C in not requiring that a class type be prefixed with its class key (the class/struct/union bit; C++-98: 9.1). This gives a cleaner and more succinct form without the typedef:



struct Info


{};


Info   info;



But if you want C compatibility, it's better to define a synonym via a typedef.

Where typedefs have really come into their own in C++ is in the fact that they can be used to define member types within classes and namespaces, which underpins a great deal of generic programming, including the traits mechanism, as shown in Listing 18.3.

Listing 18.3.


template <typename T>


struct sign_traits;





template <>


struct sign_traits<int16_t>


{


  typedef int16_t   type;


  typedef int16_t   signed_type;


  typedef uint16_t  unsigned_type;


};





template <>


struct sign_traits<uint16_t>


{


  typedef uint16_t  type;


  typedef int16_t   signed_type;


  typedef uint16_t  unsigned_type;


};



This chapter takes a close look at typedef, at some of the dangers of its use, and distinguishes between the use of typedef for conceptual type definitions and contextual type definitions. Finally, it introduces the concept of True Typedefs, and illustrates a template-based implementation of it that can be used to provide a stronger degree of type safety than is afforded by the language as it stands.


      Previous section   Next section