【问题标题】:Is std::vector::begin() - 1 undefined?std::vector::begin() - 1 是否未定义?
【发布时间】:2013-08-14 07:29:43
【问题描述】:

我需要以倒序遍历一些元素,我正在使用:

for ( /* ... */ it = vec.end() - 1, end = vec.begin() ; it >= end ; --it ) {
    // ...

我现在为某些容器定义了end() - 1,包括vector,但现在我需要知道是否也定义了begin decrement。

编辑

我不知道是否可以使用 reverse_iterator,因为我需要将这些迭代器作为参数传递给 std::vector::erase 并且从文档中看,它们是不同的类型。

【问题讨论】:

  • 是的,你为什么需要begin() - 1
  • 您可以改用rbeginrend
  • 你只能增加个不等于end的迭代器,或者减少不等于begin的迭代器。完全对称的简单规则。
  • "我现在为某些容器定义了 end() - 1" 不,不是。仅在 begin() != end() 时才定义。

标签: c++ stl iterator portability


【解决方案1】:

是的,它是未定义的。

如果您想反向迭代元素,只需使用rbeginrend。它们是反向迭代器,专门为此目的而设计的。如果需要从反向迭代器中获取标准迭代器,可以在迭代器上使用base member function

【讨论】:

  • 我不知道是否可以使用 reverse_iterator,因为我需要将这些迭代器作为参数传递给 std::vector::erase 并且从文档中,它们看起来是不同的类型.
  • 谢谢。看来我要离开UB的土地了。 :)
【解决方案2】:

这是未定义的行为。但是为什么不使用反向迭代器rbegin()rend()

std::vector<int> vec{0,1,2,3,4}
for (auto it = vec.rbegin(); it != vec.rend(); ++it) 
{
  std::cout << *it << " ";
}
std::cout << std::endl;

输出

4 3 2 1 0

【讨论】:

  • 我不知道是否可以使用 reverse_iterator,因为我需要将这些迭代器作为参数传递给 std::vector::erase 并且从文档中,它们看起来是不同的类型
  • @vinipsmaker 您可能不应该在迭代器循环内调用擦除。也许你应该解释你想要达到的目标。如果它与仅仅向后迭代相差太大,那么它应该是一个不同的问题。
  • 如果我可以开始递减,问题就解决了。从另一个问题来看,这种行为是未定义的,但是有很多原因为什么它必须起作用,除非编译器想要将if 放在依赖于这种行为的错误代码中,并且连同这个if,不必要地扼杀性能。
  • PS.:并且需要反向迭代,因为超出删除范围的元素的迭代器将失效。
  • @vinipsmaker 不需要特殊的if,您通常可以输入--begin()。例如对于std::vector,它只会做一个指针递减)。但是,即使对于 C 数组,指向开头前的一个也是未定义的行为,即使没有取消引用。未定义的行为包括您的代码将工作,除了例如当您进行现场演示时:-)
猜你喜欢
  • 1970-01-01
  • 2021-03-15
  • 2019-03-31
  • 2017-07-03
  • 1970-01-01
  • 2014-12-05
  • 2012-12-04
  • 2023-02-07
  • 1970-01-01
相关资源
最近更新 更多