std::copy,std::copy_if(3)
std::copy,std::copy_if(3) π
okay so bestie this is from the C++ Standard Libary manual β yes, the header literally says βLibaryβ π not my typo, I promise. Itβs the page for std::copy and std::copy_if, and weβre gonna copy ranges like itβs our whole personality.
πΈ NAME πΈ
std::copy,std::copy_if β std::copy,std::copy_if
no thoughts, just the same name twice, iconic π
β¨ Synopsis β¨
Defined in header <algorithm>:
template< class InputIt, class OutputIt >
OutputIt copy( InputIt first, InputIt last,
OutputIt d_first );
(1) (constexpr since C++20)
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2 >
ForwardIt2 copy( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first );
(2) (since C++17)
template< class InputIt, class OutputIt, class UnaryPred >
OutputIt copy_if( InputIt first, InputIt last,
OutputIt d_first, UnaryPred pred );
(3) (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 );
(4) (since C++17)
Copies the elements in the range, defined by [first, last), to another range beginning at d_first (copy destination range).
okay now the numbered tea:
- Copies all elements in the range
[first, last)starting fromfirstand proceeding tolast. Ifd_firstis in[first, last), the behavior is undefined. In this case,std::copy_backwardmay be used instead. - Copies the elements, but executed according to
policy. This overload participates in overload resolution only ifstd::is_execution_policy_v<std::decay_t<ExecutionPolicy>>is true. (until C++20)std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>is true. (since C++20) If[first, last)and the copy destination range overlaps, the behavior is undefined. - Only copies the elements for which the predicate
predreturnstrue. This copy algorithm is stable: the relative order of the elements that are copied is preserved. If[first, last)and the copy destination range overlaps, the behavior is undefined. - Same as (3), but executed according to
policy. This overload participates in overload resolution only ifstd::is_execution_policy_v<std::decay_t<ExecutionPolicy>>is true. (until C++20)std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>is true. (since C++20)
π Parameters π
- first, last β the range of elements to copy
- d_first β the beginning of the destination range
- policy β the execution policy to use. See execution policy for details.
- pred β unary predicate which returns
truefor the required elements. The expressionpred(v)must be convertible toboolfor every argumentvof type (possibly const)VT, whereVTis the value type ofInputIt, regardless of value category, and must not modifyv. Thus, a parameter type ofVT&is not allowed, nor isVTunless forVTa move is equivalent to a copy (since C++11).
π¦ Type requirements π¦
InputItmust meet the requirements ofLegacyInputIterator.OutputItmust meet the requirements ofLegacyOutputIterator.ForwardIt1,ForwardIt2must meet the requirements ofLegacyForwardIterator.UnaryPredmust meet the requirements ofPredicate.
π Return value π
Output iterator to the element in the destination range, one past the last element copied.
π§ Complexity π§
Given N as std::distance(first, last):
- 1, 2) Exactly
Nassignments. - 3, 4) Exactly
Napplications of the predicatepred, and at mostNassignments.
For the overloads with an ExecutionPolicy, there may be a performance cost if ForwardIt1's value type is not MoveConstructible.
π Exceptions π
The overloads with a template parameter named ExecutionPolicy report errors as follows:
- If execution of a function invoked as part of the algorithm throws an exception and
ExecutionPolicyis one of the standard policies,std::terminateis called. For any otherExecutionPolicy, the behavior is implementation-defined. - If the algorithm fails to allocate memory,
std::bad_allocis thrown.
π₯ Possible implementation π₯
copy (1)
template<class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last,
OutputIt d_first)
{
for (; first != last; (void)++first, (void)++d_first)
*d_first = *first;
return d_first;
}
copy_if (3)
template<class InputIt, class OutputIt, class UnaryPred>
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;
}
π 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.
When copying overlapping ranges, std::copy is appropriate when copying to the left (beginning of the destination range is outside the source range) while std::copy_backward is appropriate when copying to the right (end of the destination range is outside the source range).
π Example π
The following code uses std::copy to both copy the contents of one std::vector to another and to display the resulting std::vector.
// Run this code
#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';
}
Possible output:
to_vector contains: 0 1 2 3 4 5 6 7 8 9
odd numbers in to_vector are: 1 3 5 7 9
to_vector contains these multiples of 3: 0 3 6 9
π«Ά Defect reports π«Ά
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
LWG 2039β applied to C++11 β behavior as published: the return value ofstd::copy_ifwas not specified; correct behavior: specified.LWG 2044β applied to C++11 β behavior as published: the stability ofstd::copy_ifwas not defined; correct behavior: defined.
β See also β
copy_backwardβ copies a range of elements in backwards order (function template)reverse_copyβ creates a copy of a range that is reversed (function template)copy_nβ copies a number of elements to a new location (C++11) (function template)fillβ copy-assigns the given value to every element in a range (function template)remove_copy,remove_copy_ifβ copies a range of elements omitting those that satisfy specific criteria (function template)ranges::copy,ranges::copy_ifβ copies a range of elements to a new location (C++20) (niebloid)
okay bye bestie, this page came from http://cppreference.com, version 2024.06.10 β mwah πβ¨
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms