Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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();
    }
}
like image 304
Jarod42 Avatar asked Jul 09 '20 12:07

Jarod42


People also ask

Is vector iterator a pointer?

An iterator is an object (like a pointer) that points to an element inside the container. We can use iterators to move through the contents of the container. They can be visualized as something similar to a pointer pointing to some location and we can access the content at that particular location using them.

What is the difference between a pointer and an iterator?

A pointer hold an address in memory. An iterator may hold a pointer, but it may be something much more complex. For example, an iterator can iterate over data that's on file system, spread across many machines, or generated locally in a programmatic fashion.

Is Vector name a pointer?

No. std::vector is not a pointer. It is a class.

How do you change an iterator to a pointer?

Unfortunately, there is no way to convert from an iterator directly to a pointer without dereferencing the iterator ( it[0] and &*it both dereference the iterator). As a result, the only way to convert iterators to pointers that is able to handle all valid iterators requires having access to the vector in question.


1 Answers

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.

like image 185
MSalters Avatar answered Sep 21 '22 11:09

MSalters