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.