Как реструктурировать список списков в C++, используя splice()
У меня есть list
из lists
с элементами типа my_struct
, Я просматриваю каждый элемент с двумя итераторами (один для внешнего списка и один для внутренних списков) и делаю некоторые вычисления. Каждый раз, когда я передаю внутренний список, я проверяю критерий и (при необходимости) пытаюсь разделить этот внутренний список на два, используя splice()
функция. Я хочу переместить вторую часть внутреннего списка во внешний список (сразу после текущего внутреннего списка).
Вот что у меня так далеко:
std::list<std::list<my_struct>> myList;
std::list<std::list<my_struct>>::iterator outerIter;
std::list<my_struct>::iterator innerIter;
for (outerIter = myList.begin(); outerIter != myList.end(); outerIter++)
{
std::list<my_struct> &listEntry = *outerIter;
for (innerIter = listEntry.begin(); innerIter != listEntry.end(); innerIter++)
{
// some calculations
}
if (criterion)
{
myList.splice(outerIter, listEntry, innerIter, listEntry.end());
}
}
Что этот код должен сделать, это переместить std::list<my_struct>
начиная с innerIter
и заканчивается в listEntry.end()
как новый внутренний список сразу за проверенным внутренним списком.
Я надеюсь, что вы можете понять, что я имею в виду, поскольку я не знаю, как объяснить это более понятно.
Я уже опробовал разные способы написания splice
часть, но я всегда получал ошибки.
Так что, если у кого-то есть идея, как правильно запрограммировать это, я был бы очень рад получить помощь.
1 ответ
Сначала я думаю, что вы неправильно поняли, что делает функция сплайсинга.
Проблема, которую я вижу на первый взгляд, заключается в том, что вы передаете итератор innerIter
в splice
но этот итератор больше не указывает на начало, так как вы увеличили его в предыдущем цикле for.
И главная проблема:
Вы передаете элементы типа my_struct
к std::list<std::list<my_struct>>
список. Следовательно, вы получаете ошибку компиляции: вы не можете конвертировать my_struct
в std::list<my_struct>
, если вы ищете подробную ошибку, вы найдете, что _Ty
это действительно my_struct
,
Итак, вот что вам нужно сделать:
- Создайте новый список, который будет раскрывать элементы.
- передать элементы.
- Вставьте новый список в нужную вам позицию.
В C++ (предупреждение не проверено):
for (auto outerIter = myList.begin(); outerIter != myList.end(); outerIter++)
{
std::list<my_struct> &listEntry = *outerIter;
for (auto innerIter = listEntry.begin(); innerIter != listEntry.end(); innerIter++)
{
// some calculations
}
if (criterion)
{
// you need point the next element, in roder to insert after the current outerIter position.
MyList::iterator tmp = outerIter;
std::list<my_struct> list_to_insert; // 1
list_to_insert.splice(list_to_insert.begin(), listEntry, listEntry.begin(), listEntry.end()); // 2
myList.insert(++tmp, list_to_insert); // 3
}
}