It is best to think of thread safe in C++ not as a property of a single operation, but of a property of multiple operations relative to each other.
vecofAbc.at(1) ;
ABC::iterator iter = vecofAbc.end();
ABC::iterator iter = vecofAbc.begin();
each of these is mutually thread safe. They can occur in seperate threads with no data races involved.
There are operations which are not mutually thread safe with the above operations. These include
vecofAbc.push_back(some_abc);
vecofAbc.reserve(10000);
also note that
vecofAbc[0] = some_abc;
is mutually thread safe with
vecofAbc.at(1);
or
vecofAbc[1] = some_abc;
The rule is that any number of const operations on a container are mutualy threads safe, and that .begin(), end() and a number of other operations (which do not mutate container layout) are treated as const as far as this rule is concerned.
In addition, reading from/writing to an element is mutually thread safe with reading/writing from distinct elements, and reading from/writing to an element is mutually thread safe with other const operations on the container (and other operations which are treated as const by the above rule).
std::vector guarantees it will only call const methods on classes when itself is being called through const methods or through methods treated as const under the above rule. If your object's const methods fail to be mutually thread safe, all bets are off.
See Does const mean thread safe for more details.