Я уже слышал, что std::vector<T>::iterator
может быть просто T*
вместо класса итератора.
Но действительно ли это законно?
Арифметика указателя c применяется только к массиву , а std::vector
создает не объект массива (T[]
), а смежные объекты (через размещение нового ).
Более того, я думаю что std::launder
даже потребуется (C ++ 17) для доступа к отдельному элементу (как мы можем прочитать в комментарии к static_vector
, пример std::aligned_storage
).
Я думаю, это примерно эквивалентно следующему, которое я считаю неопределенным поведением.
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();
}
}