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

时间:2012-08-01 02:16:34

标签: c++ iterator

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

2 个答案:

答案 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());