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
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).