pointers support [], which is defined as p[i] being equivalent to *(p + i). RandomAccessIterators are things that behave like pointers, so they also support that, with the same meaning.
A number of containers also support []. Of these, there are two kinds.
The first kind are those SequenceContainers who's iterators are RandomAccessIterator, and the parameter to SequenceContainer::operator[] is std::size_t, i.e. something that identifies an element by it's position in the sequence. vec[i] is the same as vec.begin()[i] is the same as *(vec.begin() + i).
If you can easily find an element at a particular index, your iterators can easily be incremented or decremented by an offset larger than 1.
The second kind are those AssociativeContainers or UnorderedAssociativeContainerss that have a mapped_type. The parameter to AssociativeContainer::operator[] is AssociativeContainer::key_type, i.e. something that identifies an element by it's value.
Easily finding an element with a particular value doesn't help with moving along a sequence. It turns out that the currently known data-structures that allow easy access by value are not as good at knowing which element is n further along.