Search code examples
c++pointersiteratorlanguage-lawyerstdvector

Could std::vector::iterator legally be a pointer


I already heard that std::vector<T>::iterator can simply be T* instead of an iterator class.

But is it really legal?

Pointer arithmetic only applies to array and std::vector doesn't create array object (T[]) but contiguous objects (via placement new).

Moreover I think that std::launder would even be required (C++17) to access individual element (as we can read in comment of static_vector example of std::aligned_storage).

I think it is roughly equivalent to following that I think is undefined behavior.

template <typename T, std::size_t N, typename F>
void test_array(F func)
    typename std::aligned_storage<sizeof (T) * N, alignof (T)>::type data;
    char* buffer = &data;
    for (std::size_t i = 0; i != N; ++i) {
        new (buffer + i * sizeof(T)) T;
    }
    T* array = reinterpret_cast<T*>(buffer);
    for (std::size_t i = 0; i != N; ++i) {
        func(array[i]); // UB for (0 < i) ?
    }
    for (std::size_t i = 0; i != N; ++i) {
        array[i].~T();
    }
}

Solution

  • std::vector::iterator is part of the Standard Library, and therefore part of the implementation. That means it may depend on implementation-specific details. In particular, the implementation may use pointer arithmetic in a non-portable way. If the implementation knows a T[] is indistinguishable from contiguously allocated T's, then it can do pointer arithmetic on them.