STL алгоритм, чтобы повторить операцию удаления на втором контейнере? - PullRequest
0 голосов
/ 01 марта 2020

Жизнь дала мне следующие предметы:

  • 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?

Я легко могу решить эту проблему, например, построив v2 итераторов, используя комбинацию std::distance/advance, но мне было интересно, если STL предоставляет какой-то механизм для этого. Может быть, что-то вроде идиомы удаления-удаления в сочетании с операцией преобразования? Кажется, за пределами моего STL-фу ...

1 Ответ

3 голосов
/ 01 марта 2020

Если у вас есть итератор, вы можете получить индекс через std::distance до begin().

Если у вас есть индекс, вы можете получить итератор через 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 );

Я могу легко решить эту проблему, например, построив итераторы v2, используя комбинацию std :: distance / advance, но мне было интересно, если STL предоставляет некоторые машины для этого. Может быть, что-то вроде идиомы удаления-удаления в сочетании с операцией преобразования? Кажется, за пределами моего STL-фу ...

Я увидел редактирование только после написания ответа. Дело в том, что 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, конечно, вам нужно передать итераторы, которые ссылаются на элемент в соответствующем контейнере.

...