14

我认为&*vector::end()这是未定义的行为......直到我看到一些帖子提到了Stroustrup 的代码

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()迭代器未定义的行为,还是有效?

4

2 回答 2

7

它不一定是未定义的行为,但它取决于迭代器的具体实现:

C++03 24.1/5 迭代器要求

正如指向数组的常规指针保证有一个指针值指向数组的最后一个元素,所以对于任何迭代器类型,都有一个迭代器值指向对应容器的最后一个元素。这些值称为过去值。定义了表达式 *i 的迭代器 i 的值称为可解引用。该库从不假定过去的值是可取消引用的。

container.end()如果不可取消引用,则有问题的代码具有未定义的行为。很多时候,向量的迭代器只是一个指针——在这些情况下,没有未定义的行为。

于 2012-08-01T02:25:51.130 回答
3

这是未定义的行为。也就是说,C++ 标准未定义的行为。它可以由实现来定义。更有可能的是,它在某些情况下会碰巧起作用,而在其他情况下则不会。

在这种情况下,如果迭代器是原始指针,编译器可能会将 &*i 优化为无操作,因此它可能会起作用。Stroustrup 可能知道他的向量使用原始指针作为迭代器。

即使编译器没有优化它,在实践中,如果向量的内存恰好被分配到段边界结束,它也可能会失败。(或者如果编写迭代器实现以检查不可解引用,例如用于调试目的。)

在 C++11 中,这应该写成:

sort(container.data(), container.data()+container.size()); 
于 2012-08-01T12:01:29.287 回答