In C++, the size (in bits) of a data type is not guaranteed. Sometimes though, you need to ensure a specific size for your data types (this happens a lot when working with bit streams). These types might be typedefed so that on whatever compiler/platform the code is built on, when you need an 8-bit signed integer, you really do get an 8-bit signed integer.
Say, for example, you need a 16-bit signed integer. On one system, short might be 16 bits, and on another system, short might be 32 bits. With typedefs, it allows you to simply use int16 in your code, and then if you switch between these two different systems where short is two different sizes, you can just change the typedef to the appropriate type and your code should work just fine (rather than having to hunt down all the places in your code and make changes all over the place just to get a 16 bit integer).
Sometimes it's not so you can switch between one system and another (like in the previous example). Sometimes it's to explicitly state that you require a data type with a very specific size, and if the system does not support that size, then your code does not support that system. Saying int8 makes it very clear you require an 8 bit integer.
Of course, the typedef itself doesn't enforce the requirement (it doesn't care how big your data types are or what they're named), but using an appropriately named type in your code makes it very clear what you require. You can then, if you want, force the compilation to fail if the requirements are not met (for example, you can fail the compilation if int8 is not 8 bits, or if int16 is not 16 bits), in addition to making the requirements in the code self-documenting (because int8 "documents" the code as requiring an 8-bit signed integer, whereas just saying signed char does not "document" the code as requiring an 8-bit signed integer).