Jarod42
Jarod42

Reputation: 217235

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();
    }
}

Upvotes: 6

Views: 191

Answers (1)

MSalters
MSalters

Reputation: 179799

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.

Upvotes: 6

Related Questions