Может ли std :: vector :: iterator по закону быть указателем - PullRequest
6 голосов
/ 09 июля 2020

Я уже слышал, что 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();
    }
}

1 Ответ

4 голосов
/ 09 июля 2020

std::vector::iterator является частью стандартной библиотеки и, следовательно, частью реализации. Это означает, что это может зависеть от деталей c конкретной реализации. В частности, реализация может использовать arithmeti c указателя непереносимым способом. Если реализация знает, что T[] неотличима от непрерывно выделенных T's, тогда она может выполнить арифметику указателя c на них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...