Следующие аргументы функции insert(), расположенные после начального итератора, похожи на аргументы конструкторов контейнеров. Версия, получающая количество элементов и значение, добавляет определенное количество одинаковых элементов перед указанной позицией:

svec.insert(svec.end(), 10, "Anna");

Этот код вставляет 10 элементов в конец вектора svec и инициализирует каждый из них строкой "Anna".

Данная версия функции insert() получает пару итераторов или список инициализации для вставки элементов из данного диапазона перед указанной позицией:

vector v = {"quasi", "simba", "frollo", "scar"};

// вставить два последних элемента вектора v в начало slist

slist.insert(slist.begin(), v.end() - 2, v.end());

slist.insert(slist.end(), {"these", "words", "will",

                           "go", "at", "the", "end"});

// ошибка времени выполнения:

// обозначающие копируемый диапазон итераторы

// не должны принадлежать тому же контейнеру, который изменяется

slist.insert(slist.begin(), slist.begin(), slist.end());

При передаче пары итераторов они не могут относиться к тому же контейнеру, к которому добавляются элементы.

По новому стандарту версии функции insert(), получающие количество или диапазон, возвращают итератор на первый вставленный элемент. (В предыдущих версиях библиотеки эти функции возвращали тип void.) Если диапазон пуст, никакие элементы не вставляются, а функция возвращает свой первый параметр.

Применение возвращаемого значения функции insert()

Значение, возвращенное функцией insert(), можно использовать для многократной вставки элементов в определенной позиции контейнера:

list lst;

auto iter = lst.begin();

while (cin >> word)

 iter = lst.insert(iter, word); // то же, что и вызов push_front()

Важно понимать, почему именно цикл, подобный этому, эквивалентен вызову функции push_front().

Перед циклом итератор iter инициализируется возвращаемым значением функции lst.begin(). Первый вызов функции insert() получает только что прочитанную строку и помещает ее перед элементом, обозначенным итератором iter. Значение, возвращенное функцией insert(), является итератором на этот новый элемент. Присвоим этот итератор итератору iter и повторим цикл, читая другое слово. Пока есть слова для вставки, каждая итерация цикла while вставляет новый элемент перед позицией iter и снова присваивает ему позицию недавно вставленного элемента. Этот (новый) элемент является первым. Таким образом, каждая итерация вставляет элемент перед первым элементом в списке.

Применение функций emplace()

Новый стандарт вводит три новых функции-члена — emplace_front(), emplace() и emplace_back(), которые создают элементы, а не копируют. Они соответствуют функциям push_front(), insert() и push_back(), позволяющим помещать элемент в начало контейнера, перед указанной позицией или в конец контейнера соответственно.

Когда происходит вызов функции-члена insert() или push(), им передается объект типа элемента для копирования в контейнер. Когда происходит вызов функции emplace(), ее аргументы передаются конструктору типа элемента, который создает элемент непосредственно в области, контролируемой контейнером. Предположим, например, что контейнер с содержит элементы типа Sales_data (см. раздел 7.1.4):

// создает объект класса Sales_data в конце контейнера с

// использует конструктор класса Sales_data с тремя аргументами

с.emplace_back("978-05903534 03", 25, 15.99);

// ошибка: нет версии функции push_back(), получающей три аргумента

с.push_back("978-0590353403", 25, 15.99);

// ok: создается временный объект класса Sales_data для передачи

// функции push_back()

c.push_back(Sales_data("978-0590353403", 25, 15.99));

Перейти на страницу:

Похожие книги