【问题标题】:STL algorithm to repeat an erase operation on a second container?STL算法在第二个容器上重复擦除操作?
【发布时间】:2020-06-14 02:02:53
【问题描述】:

生活给了我以下物品:

  • std::vector<T1> v1;
  • std::vector<T2> v2;
  • typename std::vector<T1>::iterator it_first;
  • typename std::vector<T1>::iterator it_last;

以及以下约束:

  • v1.size() == v2.size() > 0
  • v1.begin() <= it_first <= it_last <= v1.end()

v1 中删除两个迭代器指向的范围是一个简单的单行,但是我如何也从v2 中删除相同的范围

我可以很容易地解决这个问题,例如使用std::distance/advance 的组合构建v2 迭代器,但我想知道STL 是否为此提供了一些机制。像擦除删除习语加上变换操作之类的东西,也许?它似乎超出了我的 STL-fu...

【问题讨论】:

  • 该范围由它的迭代器定义,它指向v1。它不是v2 中的范围,所以要非常小心您所说的“相同范围”是什么意思。
  • 我在一个名为 STLSoft 的库中找到了 eraser_iterator 的实现:github.com/synesissoftware/STLSoft-1.10/blob/beta-18/include/… 我对这种情况的可用性没有经验。

标签: c++ stl iterator containers erase


【解决方案1】:

当你有一个迭代器时,你可以通过std::distancebegin() 获取索引。

当您有索引时,您可以通过begin() + index 获取迭代器。

这基本上就是在第二个向量中获得相同范围的索引所需的全部内容。

顺便说一句,迭代器将抽象出索引。当您需要索引时,请使用索引。对于erase 那将是

size_t start = 1;
size_t end = 42;
std::erase( v1.begin() + start, v1.begin() + end );
std::erase( v2.begin() + start, v2.begin() + end );

例如,我可以通过混合使用 std::distance/advance 构建 v2 迭代器来轻松解决这个问题,但我想知道 STL 是否为此提供了一些机制。像擦除删除习语加上变换操作之类的东西,也许?它似乎超出了我的 STL-fu...

我在写完答案后才看到编辑。问题是 std::distance / std::advance 在迭代器和索引之间切换的机制。

考虑到迭代器通常用于可迭代的事物。你甚至不需要一个容器来迭代。例如,您可以编写一个迭代器类型来迭代整数。这种迭代器类型可以这样使用:

std::vector<std::string> x(100);
auto begin = int_iterator(0);
auto end   = int_iterator(100);
for ( ; begin != end; ++begin) std::cout << x[ *begin ];

这不是 C 主义。该示例可能不是最好的,但int_iterator 本身与迭代器的一般概念相当。 通常迭代器不了解底层容器(如果有的话)。很少有例外(例如insert_iterator)。在erase 的情况下,您当然需要传递引用相应容器中元素的迭代器。

【讨论】:

  • 我认为这里的重点是避免退回到索引。我从其他一些算法中得到了迭代器。我真的需要使用std::distance 返回索引并使用std::advance 返回迭代器吗?肯定没问题,但是……真的吗?
  • @DarioP 为什么你认为这会有问题?您还在寻找什么?
  • 这种做法并没有错,其实我在问题中也提到了!问题是,如果我正在使用迭代器,我不需要退回到索引或指针或任何恕我直言。我问的不是实际问题,而是关于风格和优雅的问题。
  • @DarioP 如果您需要索引,那么您需要索引。迭代器仅对单个容器有效。实际上,当您真正需要索引时使用迭代器时,我会称其为不好的样式
  • @idclev463035818 -- re:“迭代器仅对单个容器有效”-您说得对,容器中的迭代器仅对该容器有效。但是迭代器比这更抽象。迭代器指定一个范围。容器是管理范围的一种方式,但不是唯一方式。
猜你喜欢
  • 2011-04-21
  • 1970-01-01
  • 2013-04-07
  • 2013-09-21
  • 2016-04-13
  • 2021-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多