我有一个 C++ 数组:
std::array<int, 10> arr { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
我想反转最后五个元素,最终得到{ 0, 1, 2, 3, 4, 9, 8, 7, 6, 5 }
. 我知道std::array
给了我随机访问迭代器,所以我绝对可以这样写:
std::reverse(arr.begin() + 5, arr.end());
但是,我想知道其他一些可能的方法。
T*
是一个随机访问迭代器,所以我可以这样写:
std::reverse(&arr[5], &arr[arr.size()]);
我相当确定这是明确定义的,因为允许引用(但不能访问)数组的末尾一位。
我想知道是否允许这样做:
std::reverse(&arr[5], arr.end());
这在我的机器上运行,但这并不意味着它是标准行为。
如果arr
是一个C风格的数组T[]
,那么它的迭代器类型显然是T*
。但是,至少粗略地看一下,我没有看到任何与它std::array<T, C>::iterator
相同的保证T*
,甚至可以与之相媲美。
标准是否保证上述代码行有效?s是否保证与指向数组中元素的std::array<T, C>::iterator
指针兼容?T
不,
std::array<T, C>::iterator
不保证是原始T*
指针,或与原始T*
指针相当。没有什么可以阻止实现使用代理类型iterator
(以提供调试、边界检查等),就像任何其他容器类型一样。此外,
arr[arr.size()]
这是未定义的行为,因为它访问了越界的元素,因此,当您获取不存在的元素的地址时,这&arr[arr.size()]
也是未定义的行为。但是使用arr.begin()+arr.size()
和&arr[0]+arr.size()
来创建一个尾数迭代器/指针都是安全的(只要你不取消引用它们)。