When should typedef be used in C ++?

In my C ++ (MFC) programming years, I never felt the need to use typedef , so I don’t know what it is used for. Where should I use it? Are there real situations when using typedef is preferable? Or is it really more of a C keyword?

+64
c ++ typedef
Feb 05 '09 at 2:59 p.m.
source share
12 answers

Metaprogramming patterns

typedef necessary for many task metaprogramming patterns - whenever a class is considered as a function of compilation time type, typedef used as a "compilation time type value" to get the resulting type. For example. consider a simple metafound for converting a pointer type to its base type:

 template<typename T> struct strip_pointer_from; template<typename T> struct strip_pointer_from<T*> { // Partial specialisation for pointer types typedef T type; }; 

Example: an expression of type strip_pointer_from<double*>::type evaluates to double . Note that template metaprogramming is usually not used outside of library development.

Simplifying Function Pointer Types

typedef is useful for specifying a short, sharp alias for complex types of function pointers:

 typedef int (*my_callback_function_type)(int, double, std::string); void RegisterCallback(my_callback_function_type fn) { ... } 
+83
Feb 05 '09 at 15:04
source share

In Bjarne’s book, he argues that you can use typedef to solve portability problems between systems that have different integer sizes. (this is paraphrase)

On a machine where sizeof(int) is 4, you can

 typedef int int32; 

Then use int32 everywhere in your code. When you move on to a C ++ implementation where sizeof(int) is 2, you can just change the typdef

 typedef long int32; 

and your program will still work on a new implementation.

+33
Feb 05 '09 at 15:08
source share

use with function pointer

Hide function pointer declarations with typedef

 void (*p[10]) (void (*)() ); 

Only a few programmers can say that p is "an array of 10 pointers to a function that returns void, and takes a pointer to another function that returns void and takes no arguments." The cumbersome syntax is almost illegible. However, you can greatly simplify it by using typedef declarations. First, declare a typedef for "a pointer to a function that returns void and without arguments" as follows:

  typedef void (*pfv)(); 

Then declare another typedef for the "function pointer returning void and taking pfv" based on the previously declared typedef:

  typedef void (*pf_taking_pfv) (pfv); 

Now that we have created the pf_taking_pfv typedef as a synonym for the unmanaged "function pointer returning void and taking pfv", declaring an array of 10 such pointers is a breeze:

  pf_taking_pfv p[10]; 

of

+21
Feb 05 '09 at 15:05
source share

Just to provide some examples for things: STL containers.

  typedef std::map<int,Froboz> tFrobozMap; tFrobozMap frobozzes; ... for(tFrobozMap::iterator it=frobozzes.begin(); it!=map.end(); ++it) { ... } 

It is not standard to even use typedef, for example

 typedef tFrobozMap::iterator tFrobozMapIter; typedef tFrobozMap::const_iterator tFrobozMapCIter; 

Another example: using shared pointers:

 class Froboz; typedef boost::shared_ptr<Froboz> FrobozPtr; 



[update] According to the comment - where to put them?

The final example - using shared_ptr - is easy: this is the true header material - or at least the direct header. In any case, you will need a forward declaration for shared_ptr, and one of its claimed advantages is that it is safe to use with forward decl.

Share with others: if there is shared_ptr, you should probably use this type only through shared_ptr, so splitting ads doesn't make much sense.

(Yes, xyzfwd.h is a pain. I would use them only in hot spots - knowing that hot spots are difficult to identify. Call the compilation model + C ++ ...)

Container typedefs I usually use where a container variable is declared. locally for local var as members of a class when the actual container instance is a member of the class. This works well if the actual type of container is an implementation detail without causing additional dependency.

If they become part of a specific interface, they are declared together with the interface with which they are used, for example,

 // FrobozMangler.h #include "Froboz.h" typedef std::map<int, Froboz> tFrobozMap; void Mangle(tFrobozMap const & frobozzes); 

This becomes problematic when the type is a binding element between different interfaces - i.e. the same type is needed for multiple headers. Some solutions:

  • declare it together with the specified type (suitable for containers that are often used for this type).
  • move them to a separate header
  • go to a separate header and make it a data class, where the actual container again is an implementation.

I agree that the last two are not so big, I will use them only when I get into trouble (not proactively).

+17
Feb 05 '09 at 15:14
source share

typedef is useful in many situations.

This basically allows you to create an alias for the type. When / if you need to change the type, the rest of the code may not change (this, of course, depends on the code). For example, suppose you want to use iter for a C ++ vector

 vector<int> v; ... for(vector<int>::const_iterator i = v->begin(); i != v.end(); i++) { // Stuff here } 

In the future, you might consider changing the combo vector because the type of operations you should do with it. Without a typedef, you must change ALL occurrences of the vector in your code. But if you write something like this:

 typedef vector<int> my_vect; my_vect v; ... for(my_vect::const_iterator i = v->begin(); i != v.end(); i++) { // Stuff here } 

Now you just need to change one line of code (from " typedef vector<int> my_vect " to " typedef list<int> my_vect "), and everything works.

typedef also saves you time when you have complex data structures that take a very long time to write (and are hard to read)

+5
Feb 05 '09 at 15:12
source share

One good reason to use typedef is that the type of something can change. For example, let's say that at the moment, 16-bit ints are great for indexing a certain data set, because in the foreseeable future you will have less than 65535 elements, and space limitations are significant or you need good cache performance. However, if you need to use your program in a data set with more than 65535 elements, you want to be able to easily switch to a wider integer. Use typedef and you only need to change this in one place.

+5
Feb 05 '09 at 15:13
source share

typedef not only allows you to have an alias for complex types, but also gives you a natural place to document type. I sometimes use this for documentation purposes.

There are also cases when I use an array of bytes. Now an array of bytes can mean a lot of things. typedef allows me to define my byte array as "hash32" or "fileContent" to make my code more readable.

+4
Mar 19 '13 at 0:28
source share

Using typedef in the real world:

  • providing friendly aliases for long template types
  • providing friendly aliases for function pointer types
  • providing local labels for types, for example:

     template<class _T> class A { typedef _T T; }; template<class _T> class B { void doStuff( _T::T _value ); }; 
+2
Feb 05 '09 at 15:03
source share

There is one other use case for typedef when we want to include the Container view Independent code (but not for sure!)

Say you have a class:

 Class CustomerList{ public: //some function private: typedef list<Customer> CustomerContainer; typedef CustomerContainer::iterator Cciterator; }; 

The above code encapsulates the implementation of the internal container using typedef, and even if in the future the list container needs to be changed to a vector or deque, the user of the CustomerList class does not need to worry about a specific container implementation.

Consequently, typedef encapsulates and somewhat helps us write Container Independent code

+2
Jul 20 '15 at 10:14
source share

Whenever it makes the source more comprehensible or better read.

I am using typedef type in C # for generics / templates. "NodeMapping" is simply better to read / use and understand then a lot of "Dictionary <string, XmlNode>". IMHO. Therefore, I recommend it for templates.

0
Feb 05 '09 at 15:04
source share

Typedef provides flexibility in your class. If you want to change the data type in the program, you do not need to change several locations, but just need to change one occurrence.

 typedef <datatype example int or double> value_type 

you can specify the name nay instead of value_type , but value_type usually the default name.

So you can use typedef as

 value_type i=0; //same as a int or double i=0; 
0
Feb 11 '17 at 21:12
source share

... and you don't need a Typedef for an enumeration or structure.

Or you?

 typedef enum { c1, c2 } tMyEnum; typedef struct { int i; double d; } tMyStruct; 

better to write how

 enum tMyEnum { c1, c2 } struct tMyStruct { int i; double d; }; 

It is right? How about C?

-2
Feb 05 '09 at 15:31
source share



All Articles