Well, the size_type of any container (or std::string) is just the preferred type for indices and sizes related to that container. It is usually fine to use another integer type, such as int. There are a few dangers associated with not using size_type but they are very unlikely to happen in nearly all circumstances.

For example, if you do this for-loop:

for(int i = 0; i < str.size(); ++i)
...

The type of size() is size_type, and if that type is larger than int, then the value returned by str.size() could larger than what can be represented by the int type. This will lead to an infinite loop because when i reaches the maximum of its range, it will wrap around to the minimum of its range (large negative number) and the whole thing will never stop because i can never reach a value larger than size().

Using size_type guarantees that you won't get those kinds of problems, but obviously, you can see that such problems won't occur when the sizes or indices are small. So, just consider using size_type as the "playing it safe" option, which is what you would do when writing industrial-strength code.

I'm not a big fan of using typedefs to hide a pointer type. I just adds confusion and usually doesn't make the syntax simpler, often the opposite (int* becomes IntPtr or something like that). Even when using smart-pointers (as one should!) like std::unique_ptr or std::shared_ptr, you still need to make it clear in the name of the typedef what kind of smart-pointer it is, like std::unique_ptr<int> becomes IntUniquePtr, which is again not a huge gain in terms of syntax, and it often still leads to some confusion or some non-idiomatic code.

Other practical reasons people use typedefs are:

Reduce large template types and nested types to something smaller for within the body of a function, like so:

Naming the actual type only in a single place, instead of everywhere where it is used. Like this:

template <typename T>
class vector {
public:
typedef std::size_t size_type;
size_type size() const;
size_type capacity() const;
void resize(size_type new_sz);
...
// If std::size_t was used everywhere, then changing it would mean
// you would have to change it everywhere. But now, you only have
// to change the typedef.
// Note that the same is true for within a large function.
};

Hide away template types to make them appear as simple types, like this example from the standard (the std::string class):