The first form is efficient only if vector.size() is a fast operation. This is true for vectors, but not for lists, for example. Also, what are you planning to do within the body of the loop? If you plan on accessing the elements as in
T elem = some_vector[i];
then you’re making the assumption that the container has
operator(std::size_t) defined. Again, this is true for vector but not for other containers.
The use of iterators bring you closer to container independence. You’re not making assumptions about random-access ability or fast
size() operation, only that the container has iterator capabilities.
You could enhance your code further by using standard algorithms. Depending on what it is you’re trying to achieve, you may elect to use
std::transform() and so on. By using a standard algorithm rather than an explicit loop you’re avoiding re-inventing the wheel. Your code is likely to be more efficient (given the right algorithm is chosen), correct and reusable.