Как работает сращивание?
Я читал об этом в http://www.cplusplus.com/reference/list/list/splice/
Я не мог понять эту часть из кода в ссылке выше:
mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());
Представьте, что у вас есть список целых чисел со следующим содержанием:
[1, 2, 3, 4, 5]
Теперь вы создаете итератор в списке под названием it
и вы продвигаете его на 3 позиции:
[1, 2, 3, 4, 5]
^
'it' points here
затем вы разделяете список на себя, на начало списка (первый параметр), в том же списке (второй параметр), с позиции, указанной it
(третий параметр), до конца (четвертый параметр), который дает следующий результат:
[4, 5, 1, 2, 3]
Таким образом, вы фактически повернули список из двух элементов вправо.
Причина, по которой вам нужно предоставить источник list
в том, что иначе элементы не могут быть удалены из него.
Четвертый параметр функции сращивания перемещает (не копирует) ваш диапазон в положение, указанное первым параметром.
В вашем примере вы перемещаете элементы своего списка на другую позицию в списке (точнее, конец списка в начало).
void list<T,Allocator>::splice ( iterator position, list<T,Allocator>& x, iterator i );
void list<T,Allocator>::splice ( iterator position, list<T,Allocator>& x, iterator start, iterator finish );
Это довольно трудно увидеть, просто взглянув на него, потому что у нас есть 2 списка и 2 итератора.
Слово position
отдает это все же. Он заявляет, где выполнить insert
,
Итератор, который является i
это то, что движется Во второй перегрузке диапазон от start
в finish
но нет finish
Сам переехал. finish
может быть конец списка.
position
должен принадлежать this
список. Итератор должен принадлежать x
список. Элементы вставляются непосредственно перед position
в исходном (этом) списке и одновременно удаляются из x
список.
Обратите внимание, что cplusplus.com утверждает, что итераторы становятся недействительными после объединения, однако на самом деле это не так, они остаются действительными.
cplusplus.com прав в том, что position
не может быть одним из соединенных элементов (в случае, если списки совпадают)
В вашем примере:
mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());
it
должен быть итератором в mylist1. Казалось бы, это не должно быть mylist1.begin()
,
Ваша операция перемещает все элементы из it
вперед к началу списка.