Итератор становится недействительным после вставки в boost::multi_index?

Согласно документации, итераторы хэшированного индекса остаются в силе, когда новые элементы вставляются в multi_index. Однако, когда я попытался использовать следующий подход

auto& myIndex = myMultiIndex.get<0>();
auto range = myIndex.equal_range(x);
for (auto iter = range.first; iter != range.second; ++iter) {
    myMultiIndex.emplace(someArgsRelatedToIter);
}

кажется, что range.first/range.second становится недействительным: хотя std::distance(range.first, range.second) == 1, цикл for фактически выполняется дважды. Я как-то не правильно его использую? Спасибо!


person Niko    schedule 22.08.2018    source источник
comment
Я подозреваю, что ваш конечный итератор обновляется, когда вы добавляете новые вещи в myMultiIndex. Непонятно, зачем добавлять аргументы в такой цикл. Возможно, вместо этого вы можете измерить distance и выполнить цикл для этого, чтобы получить auto size = std::distance(range.first, range.second);, затем for (size_t index = 0; index < size; ++index) и таким образом добавить свои аргументы? Это всего лишь предположения, поэтому я не ответил как таковой.   -  person Tas    schedule 22.08.2018
comment
@Извините за путаницу, я на самом деле пытаюсь продублировать элементы в диапазоне с некоторыми обновленными параметрами (что-то вроде emplace(iter->oldParam, newParam)). Может быть, есть лучший способ добиться этого?   -  person Niko    schedule 22.08.2018


Ответы (1)


Когда библиотеки C++ указывают, что итераторы не аннулируются операцией, это означает, что итераторы по-прежнему указывают на один и тот же элемент. Например, в следующем коде:

std::list< int > l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
auto first = l.begin();
auto last = std::find(l.begin(), l.end(), 3);
std::cout << *first << std::endl;
std::cout << *last << std::endl;

1, 3 и 2 печатаются. Если мы теперь вставим некоторые элементы:

l.insert(last, 4);
l.insert(last, 5);
std::cout << *first << "\n";
std::cout << *last << "\n";
std::cout << std::distance(first, last) << "\n";

first и last по-прежнему действительны и указывают на одни и те же элементы, но расстояние теперь равно 4, поэтому они указывают на другой диапазон.

person Alan Birtles    schedule 22.08.2018