Использование merge
merge
не изменяется. Итератор вывода, в который помещаются результаты, должен иметь достаточно места для помещения в него числа элементов, равного сумме длин входных последовательностей. Этого можно добиться, явно зарезервировав достаточно места либо, как это сделано в примере 7.5, использовав back_inserter
:merge(v1.begin(), v1.end(), v2.begin(), v2.end(),
back_inserter(v3));
back_inserter
, который предоставляет удобный способ создания выходного итератора, который каждый раз, когда ему присваивается значение, вызывает для последовательности метод push_back
. Таким образом, вам не требуется явно изменять размер выходной последовательности. Следующий вызов создает back_inserter
для vector
с именем v3
.back_inserter(v3);
Указывать аргументы шаблона не требуется, так как back_inserter
back_inserter
Однако заметьте, что иногда вам потребуется явно указывать размер выходной последовательности, особенно при использовании в качестве такой последовательности vector
vector
при добавлении в него элементов с помощью push_back
может потребовать изменений своего размера, а это очень дорогостоящая операция. За подробностями обратитесь к рецепту 6.2.Если в последовательностях есть два одинаковых элемента, то элемент из первой последовательности будет предшествовать элементу из второй. Следовательно, если дважды вызвать merge
Объединение двух list
Рассмотрим список строк из примера 7.5:
lstStr1.sort(); // Сортируем, или объединение даст мусор!
lstStr2.sort(),
lstStr1.merge(lstStr2); // Это list::merge
Есть две причины, по которым этот код отличается от вызова std::merge
list
должны иметь один и тот же тип элементов. Это требование следует из объявления list::merge
, которое имеет вид:void merge(list
template
void merge(list
Где T
string
.Второе отличие состоит в том, что list::merge
std::merge
оставляет две входные последовательности неизменными. Скорее всего list::merge
будет обладать лучшей производительностью, так как в большинстве случаев элементы списка не копируются, а перекомпонуются, но такая перекомпоновка не гарантируется, так что с целью выяснения реального поведения требуются эксперименты.Также объединить две непрерывные последовательности можно с помощью inplace_merge
inplace_merge
отличается от merge
, так как он объединяет две последовательности «на месте». Другими словами, если есть две непрерывные последовательности (т.е. они являются частями одной и той же последовательности) и они отсортированы и требуется отсортировать общую последовательность, то вместо алгоритма сортировки можно использовать inplace_merge
. Преимущество inplace_merge
заключается в том, что при наличии достаточного объема памяти его работа занимает линейное количество времени. Если же памяти недостаточно, то он занимает Объявление inplace_merge
void inplace_merge(Bid first, Bid mid, Bid last);
void inplace_merge(Bid first, Bid mid, Bid last, BinPred comp)
inplace_merge
merge
, для определения относительного порядка элементов он по умолчанию использует operator<
, а при наличии — comp
.7.6. Сортировка диапазона