std::merge
| Defined in header <algorithm>
|
||
template< class InputIt1, class InputIt2, class OutputIt >
OutputIt merge( InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2,
OutputIt d_first );
|
(1) | (constexpr since C++20) |
template< class InputIt1, class InputIt2,
class OutputIt, class Compare >
OutputIt merge( InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2,
OutputIt d_first, Compare comp );
|
(2) | (constexpr since C++20) |
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2, class ForwardIt3 >
ForwardIt3 merge( ExecutionPolicy&& policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,
ForwardIt3 d_first );
|
(3) | (since C++17) |
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2,
class ForwardIt3, class Compare >
ForwardIt3 merge( ExecutionPolicy&& policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,
ForwardIt3 d_first, Compare comp );
|
(4) | (since C++17) |
Constructs a hypothetical sorted sequence containing all elements from two sorted source ranges [first1, last1) and [first2, last2). Copies all elements of the sequence to the destination range beginning at d_first.
For each group of equivalent elements in the sequence, any pair of elements from the group has the following order:
- If the two elements are from the same source range, the order between them in the sequence follows the original order between them in the source range.
- Otherwise, the element from the first source range is always placed before the element from the second source range.
operator<(until C++20)std::less{}(since C++20).operator<(until C++20)std::less{}(since C++20), the behavior is undefined.comp.comp, the behavior is undefined.policy.true:
|
|
(until C++20) |
|
|
(since C++20) |
If the destination range overlaps with any of the two source ranges, the behavior is undefined.
Parameters
| first1, last1 | - | the pair of iterators defining the first source range |
| first2, last2 | - | the pair of iterators defining the second source range |
| d_first | - | the beginning of the destination range |
| comp | - | comparison function object (i.e. an object that satisfies the requirements of Compare) which returns true if the first argument is less than (i.e. is ordered before) the second. The signature of the comparison function should be equivalent to the following:
While the signature does not need to have |
| policy | - | the execution policy to use |
| Type requirements | ||
-InputIt1, InputIt2 must meet the requirements of LegacyInputIterator.
| ||
-ForwardIt1, ForwardIt2, ForwardIt3 must meet the requirements of LegacyForwardIterator.
| ||
-OutputIt must meet the requirements of LegacyOutputIterator.
| ||
-Compare must meet the requirements of Compare.
| ||
Return value
The past-the-end iterator of the destination range.
Complexity
Given
- N1 as
std::distance(first1, last1), - N2 as
std::distance(first2, last2):
operator<(until C++20)std::less{}(since C++20).comp.operator<(until C++20)std::less{}(since C++20).comp.Exceptions
- If the temporary memory resources required for parallelization are not available, std::bad_alloc is thrown.
- If an uncaught exception is thrown while accessing objects via an algorithm argument, the behavior is determined by the execution policy (for standard policies, std::terminate is invoked).
Notes
This algorithm performs a similar task as std::set_union does. Both consume two sorted source ranges and produce a sorted output with elements from both inputs. The difference between these two algorithms is with handling values from both source ranges which compare equivalent (see notes on LessThanComparable).
If any equivalent values appeared n1 times in the first range and n2 times in the second, std::merge would output all n1 + n2 occurrences whereas std::set_union would output std::max(n1, n2) ones only. So std::merge outputs exactly std::distance(first1, last1) + std::distance(first2, last2) values and std::set_union may produce fewer.
Possible implementation
See also the implementations in libstdc++ and libc++.
| merge (1) |
|---|
template<class InputIt1, class InputIt2, class OutputIt>
OutputIt merge(InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2,
OutputIt d_first)
{
for (; first1 != last1; ++d_first)
{
if (first2 == last2)
return std::copy(first1, last1, d_first);
if (*first2 < *first1)
{
*d_first = *first2;
++first2;
}
else
{
*d_first = *first1;
++first1;
}
}
return std::copy(first2, last2, d_first);
}
|
| merge (2) |
template<class InputIt1, class InputIt2,
class OutputIt, class Compare>
OutputIt merge(InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2,
OutputIt d_first, Compare comp)
{
for (; first1 != last1; ++d_first)
{
if (first2 == last2)
return std::copy(first1, last1, d_first);
if (comp(*first2, *first1))
{
*d_first = *first2;
++first2;
}
else
{
*d_first = *first1;
++first1;
}
}
return std::copy(first2, last2, d_first);
}
|
Example
#include <algorithm>
#include <functional>
#include <iterator>
#include <random>
#include <print>
#include <vector>
int main()
{
// fill the vectors with random numbers
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<> dis(0, 9);
std::vector<int> v1(10), v2(10);
std::generate(v1.begin(), v1.end(), std::bind(dis, std::ref(mt)));
std::generate(v2.begin(), v2.end(), std::bind(dis, std::ref(mt)));
std::print("Originally:\nv1: {}\nv2: {}\n", v1, v2);
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
std::print("After sorting:\nv1: {}\nv2: {}\n", v1, v2);
// merge
std::vector<int> dst;
std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(dst));
std::print("After merging:\ndst: {}", dst);
}
Possible output:
Originally:
v1: [3, 4, 9, 5, 9, 9, 9, 7, 3, 2]
v2: [6, 2, 9, 0, 9, 4, 0, 1, 9, 1]
After sorting:
v1: [2, 3, 3, 4, 5, 7, 9, 9, 9, 9]
v2: [0, 0, 1, 1, 2, 4, 6, 9, 9, 9]
After merging:
dst: [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 9, 9, 9, 9, 9, 9, 9]
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 780 | C++98 | the merge operation was not defined | defined |
See also
(C++20) |
merges two sorted ranges (algorithm function object) |
| merges two ordered ranges in-place (function template & algorithm function object) | |
(C++20) |
|
(C++11) |
checks whether a range is sorted (function template & algorithm function object) |
(C++20) |
|
| computes the union of two sets (function template & algorithm function object) | |
(C++20) |
|
| sorts a range of elements (function template & algorithm function object) | |
(C++20) |
|
| sorts a range of elements while preserving relative order between equivalent elements (function template & algorithm function object) | |
(C++20) |