std::vector::iterator 可以合法地成为指针吗
Could std::vector::iterator legally be a pointer
我已经听说 std::vector<T>::iterator
可以简单地成为 T*
而不是迭代器 class。
但这真的合法吗?
Pointer arithmetic 仅适用于 array 而 std::vector
不创建数组对象 (T[]
) 但连续对象(通过 位置新).
而且我认为 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
).
我认为这大致相当于以下我认为是未定义的行为。
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();
}
}
std::vector::iterator
是标准库的一部分,因此也是实现的一部分。这意味着它可能取决于特定于实现的细节。特别是,该实现可能以不可移植的方式使用指针算法。如果实现知道 T[]
与连续分配的 T's
无法区分,那么它可以对它们进行指针运算。
我已经听说 std::vector<T>::iterator
可以简单地成为 T*
而不是迭代器 class。
但这真的合法吗?
Pointer arithmetic 仅适用于 array 而 std::vector
不创建数组对象 (T[]
) 但连续对象(通过 位置新).
而且我认为 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
).
我认为这大致相当于以下我认为是未定义的行为。
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();
}
}
std::vector::iterator
是标准库的一部分,因此也是实现的一部分。这意味着它可能取决于特定于实现的细节。特别是,该实现可能以不可移植的方式使用指针算法。如果实现知道 T[]
与连续分配的 T's
无法区分,那么它可以对它们进行指针运算。