我认为&*vector::end()
是未定义的行为......直到我看到some post引用Stroustrup's code:
void vector_pointer_test(element_t* first, element_t* last, int number_of_times)
{
vector<element_t> container(first, last);
// &*container.begin() gets us a pointer to the first element
sort(&*container.begin(), &*container.end());
unique(&*container.begin(), &*container.end());
}
解除引用end()
迭代器未定义的行为,还是有效?
答案 0 :(得分:7)
它不一定是未定义的行为,但它取决于迭代器的具体实现:
C ++ 03 24.1 / 5迭代器要求
就像指向数组的常规指针一样,确保存在 指针值指向数组的最后一个元素,因此对于任何 迭代器类型有一个指向过去的迭代器值 相应容器的元素。调用这些值 过去的价值观。迭代器的值i为其表达式 * i被定义称为可解除引用。该库从不假设过去的值是可解除引用的。
如果container.end()
无法解除引用,则相关代码具有未定义的行为。很多时候,向量的迭代器只是一个指针 - 在这种情况下,没有未定义的行为。
答案 1 :(得分:3)
这是未定义的行为。也就是说,行为不是由C ++标准定义的。它可以由实现来定义。更有可能的是,它会在某些情况下偶然发生,而不是其他情况。
在这种情况下,如果迭代器是原始指针,编译器可能会将&amp; * i优化为no-op,因此它可能会起作用。 Stroustrup可能已经知道他的向量使用原始指针作为迭代器。
即使编译器没有对其进行优化,实际上,如果向量的内存恰好被分配到段边界处,它也可能会失败。 (或者,如果编写迭代器实现以检查是否不可解除引用,例如用于调试目的。)
在C ++ 11中,这应该写成:
sort(container.data(), container.data()+container.size());