是&*vector :: end()未定义的行为?

Meh*_*dad 14 c++ iterator

我认为&*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()); 
}
Run Code Online (Sandbox Code Playgroud)

是解引用end()迭代器未定义的行为,还是有效?

Mic*_*urr 7

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

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

正如指向数组的常规指针一样,它保证指针值指向数组的最后一个元素,因此对于任何迭代器类型,都有一个迭代器值指向相应容器的最后一个元素.这些值称为past-the-end值.定义表达式*i的迭代器i的值称为可解除引用.库从不假设过去的值是可解除引用的.

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


Bra*_*don 3

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

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

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

在 C++11 中应该写成:

sort(container.data(), container.data()+container.size()); 
Run Code Online (Sandbox Code Playgroud)