std::copy, std::copy_if
Header: <algorithm>
Copies elements from a source range into a destination range.
# Declarations
template< class InputIt, class OutputIt >
OutputIt copy( InputIt first, InputIt last,
OutputIt d_first );
(constexpr since C++20)
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2 >
ForwardIt2 copy( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first );
(since C++17)
template< class InputIt, class OutputIt, class UnaryPred >
OutputIt copy_if( InputIt first, InputIt last,
OutputIt d_first, UnaryPred pred );
(since C++11) (constexpr since C++20)
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2, class UnaryPred >
ForwardIt2 copy_if( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, UnaryPred pred );
(since C++17)
# Parameters
first, last: the range of elements to copyd_first: the beginning of the destination rangepolicy: the execution policy to usepred: unary predicate used bycopy_if; for eachvof type (possibly const)VTwhereVTis the value type ofInputIt,pred(v)must be valid, convertible tobool, and must not modifyv
Type requirements:
InputItmust satisfy LegacyInputIterator.OutputItmust satisfy LegacyOutputIterator.ForwardIt1andForwardIt2must satisfy LegacyForwardIterator.UnaryPredmust satisfy Predicate.
# Return value
Output iterator to the element in the destination range, one past the last element copied.
# Complexity
Let N = std::distance(first, last).
copy: exactlyNassignmentscopy_if: exactlyNpredicate applications and at mostNassignments
# Exceptions
For overloads taking an execution policy:
- if a function invoked as part of the algorithm throws and the policy is one of the standard execution policies,
std::terminateis called - for other execution-policy types, behavior is implementation-defined
- if allocation fails,
std::bad_allocmay be thrown
# Notes
In practice, implementations of std::copy avoid multiple assignments and use bulk copy functions such as std::memmove if the value type is TriviallyCopyable and the iterator types satisfy LegacyContiguousIterator.
The destination range must have enough space for the copied elements unless an inserting iterator such as std::back_inserter is used.
Both algorithms preserve the relative order of copied elements.
If source and destination ranges overlap, the destination start must not be inside [first, last). For right-shift overlap cases, use copy_backward.
# Possible implementation
template<class InputIt, class OutputIt>
constexpr OutputIt copy(InputIt first, InputIt last, OutputIt d_first)
{
for (; first != last; (void)++first, ++d_first)
*d_first = *first;
return d_first;
}
template<class InputIt, class OutputIt, class UnaryPred>
constexpr OutputIt copy_if(InputIt first, InputIt last,
OutputIt d_first, UnaryPred pred)
{
for (; first != last; ++first)
if (pred(*first))
{
*d_first = *first;
++d_first;
}
return d_first;
}
# Example
#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
int main()
{
std::vector<int> from_vector(10);
std::iota(from_vector.begin(), from_vector.end(), 0);
std::vector<int> to_vector;
std::copy(from_vector.begin(), from_vector.end(),
std::back_inserter(to_vector));
// or, alternatively,
// std::vector<int> to_vector(from_vector.size());
// std::copy(from_vector.begin(), from_vector.end(), to_vector.begin());
// either way is equivalent to
// std::vector<int> to_vector = from_vector;
std::cout << "to_vector contains: ";
std::copy(to_vector.begin(), to_vector.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
std::cout << "odd numbers in to_vector are: ";
std::copy_if(to_vector.begin(), to_vector.end(),
std::ostream_iterator<int>(std::cout, " "),
[](int x) { return x % 2 != 0; });
std::cout << '\n';
std::cout << "to_vector contains these multiples of 3: ";
to_vector.clear();
std::copy_if(from_vector.begin(), from_vector.end(),
std::back_inserter(to_vector),
[](int x) { return x % 3 == 0; });
for (const int x : to_vector)
std::cout << x << ' ';
std::cout << '\n';
}
# Defect reports
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 2039 | C++11 | the return value of std::copy_if was not specified | specified |
| LWG 2044 | C++11 | the stability of std::copy_if was not defined | defined |