When should I use typedef in C++?

C++Typedef

C++ Problem Overview


In my years of C++ (MFC) programming in I never felt the need to use typedef, so I don't really know what is it used for. Where should I use it? Are there any real situations where the use of typedef is preferred? Or is this really more a C-specific keyword?

C++ Solutions


Solution 1 - C++

Template Metaprogramming

typedef is necessary for many template metaprogramming tasks -- whenever a class is treated as a "compile-time type function", a typedef is used as a "compile-time type value" to obtain the resulting type. E.g. consider a simple metafunction 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: the type expression strip_pointer_from<double*>::type evaluates to double. Note that template metaprogramming is not commonly used outside of library development.

Simplifying Function Pointer Types

typedef is helpful for giving a short, sharp alias to complicated function pointer types:

typedef int (*my_callback_function_type)(int, double, std::string);

void RegisterCallback(my_callback_function_type fn) {
    ...
}

Solution 2 - C++

In Bjarne's book he states that you can use typedef to deal with portability problems between systems that have different integer sizes. (this is a paraphrase)

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

typedef int int32;

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

typedef long int32;

and your program will still work on the new implementation.

Solution 3 - C++

use with function pointer

Hide Function Pointer Declarations With a typedef

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

Only few programmers can tell that p is an "array of 10 pointers to a function returning void and taking a pointer to another function that returns void and takes no arguments." The cumbersome syntax is nearly indecipherable. However, you can simplify it considerably by using typedef declarations. First, declare a typedef for "pointer to a function returning void and taking no arguments" as follows:

  typedef void (*pfv)();

Next, declare another typedef for "pointer to a function returning void and taking a pfv" based on the typedef we previously declared:

 typedef void (*pf_taking_pfv) (pfv);

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

  pf_taking_pfv p[10];

from

Solution 4 - C++

Just to provide some examples for the things said: STL containers.

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

It is not unusual to even use typedefs like

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

Another example: using shared pointers:

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

[update] As per comment - where to put them?

The last example - using shared_ptr - is easy: are true header material - or at least a forward header. You do need the forward declaration for shared_ptr anyway, and one of its declared advantages is that it's safe to use with a forward decl.

Put it another way: If there is a shared_ptr you probably should use the type only through a shared_ptr, so separating the declarations doesn't make much sense.

(Yes, xyzfwd.h is a pain. I'd use them only in hotspots - knowing that hotspots are hard to identify. Blame the C++ compile+link model...)

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

If they become part of a particular interface, they are declared together with the interface they are used with, e.g.

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

That gets problematic when the type is a binding element between different interfaces - i.e. the same type is needed by multiple headers. Some solutions:

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

I agree that the two latter aren't that great, I'd use them only when I get into trouble (not proactively).

Solution 5 - C++

typedef is useful in a lot of situations.

Basically it allows you to create an alias for a type. When/if you have to change the type, the rest of the code could be unchanged (this depends on the code, of course). For example let's say you want to iter on a c++ vector

vector<int> v;

...

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

// Stuff here

}

In the future you may think to change the vector with a list, because the type of operations you have to do on it. Without typedef you have to change ALL occurrences of vector within 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 have to change one row of code (i.e 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 which are very long to write (and difficult to read)

Solution 6 - C++

One good reason to use typedef is if the type of something may change. For example, let's say that for now, 16-bit ints are fine for indexing some dataset because for the foreseeable future, you'll have less than 65535 items, and that space constraints are significant or you need good cache performance. However, on the off chance that you need to use your program on a dataset with more than 65535 items, you want to be able to easily switch to a wider integer. Use a typedef, and you only have to change this in one place.

Solution 7 - C++

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

There are also times when I use an array of bytes. Now, an array of bytes could mean a lot of things. typedef makes it handy to define my byte array as "hash32", or "fileContent" to make my code more readable.

Solution 8 - C++

Real-world uses of typedef:

  • providing friendly aliases for long-winded templated types

  • providing friendly aliases for function pointer types

  • providing local labels for types, e.g.:

      template<class _T> class A
      {
          typedef _T T;
      };
      
      template<class _T> class B
      {
          void doStuff( _T::T _value );
      };
    

Solution 9 - C++

There is one another use case to use typedef is when we want to enable a kind of Container Independent code (but not exactly!)

Let us say you have class:

Class CustomerList{

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

The above code encapsulates the internal container implementation using typedef and even if in future the list container needs to changed to vector or deque still the user of the CustomerList class doesn't need to worry about exact container implementation.

Hence, the typedef encapsulates and somewhat help us to write Container Independent code

Solution 10 - C++

Whenever it makes the source clearer or better to read.

I use kind of typedef in C# for generics/templates. A "NodeMapping" is just better to read/use and understand then a lot of "Dictionary<string, XmlNode>". IMHO. So I'd recommend it for templates.

Solution 11 - C++

Typedef allows flexibility in your class. When you want to change the data type in the program, you do not need to change multiple locations but just need to change one occurrence.

typedef <datatype example  int or double> value_type

you can give nay name instead of value_type, but value_type is normally the standard name.

So u can use typedef like

value_type i=0;     //same as a int or double i=0; 

Solution 12 - C++

1 practical example of typedef is size_t. It is guaranteed to be big enough to contain the size of the biggest object the host system can handle. The maximum permissible size is dependent on the compiler; if the compiler is 32 bits then it is simply a typedef for unsigned int but if the compiler is 64 bits then it would be a typedef for unsigned long long. The size_t data type is never negative.

Solution 13 - C++

... and you Don't Need a Typedef for an enum or a struct.

Or do you?

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

can be better written as

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

Is that correct? What about C?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondjeidotView Question on Stackoverflow
Solution 1 - C++j_random_hackerView Answer on Stackoverflow
Solution 2 - C++Jason PunyonView Answer on Stackoverflow
Solution 3 - C++yesraajView Answer on Stackoverflow
Solution 4 - C++peterchenView Answer on Stackoverflow
Solution 5 - C++EmilianoView Answer on Stackoverflow
Solution 6 - C++dsimchaView Answer on Stackoverflow
Solution 7 - C++ZtyxView Answer on Stackoverflow
Solution 8 - C++moonshadowView Answer on Stackoverflow
Solution 9 - C++Imran Al NoorView Answer on Stackoverflow
Solution 10 - C++LeonidasView Answer on Stackoverflow
Solution 11 - C++snehaView Answer on Stackoverflow
Solution 12 - C++Rana VivekView Answer on Stackoverflow
Solution 13 - C++xtoflView Answer on Stackoverflow