Przejdź do głównej zawartości

std::copy_if() algorithm

// (1)
template< class InputIt, class OutputIt, class UnaryPredicate >
constexpr OutputIt copy_if( InputIt first, InputIt last,
OutputIt d_first,
UnaryPredicate pred );

// (2)
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2, class UnaryPredicate >
ForwardIt2 copy_if( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first,
UnaryPredicate pred );

Copies the elements in the range, defined by [first; last), to another range beginning at d_first.

  • (1) Only copies the elements for which the predicate pred returns true.

    Undefined Behaviour

    The behavior is undefined if d_first is within the range [first; last).

  • (2) Same as (1), but executed according to policy.

Overload Resolution

These overloads participate in overload resolution only if std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>  (do C++20) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>  (od C++20) is true.

Parameters

first
second

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 true for the required elements.

The expression p(v) must be convertible to bool for every argument v of type (possibly const) VT, where VT is the value type of InputIt, regardless of value category, and must not modify v. Thus, a parameter type of VT& is not allowed , nor is VT unless for VT a move is equivalent to a copy. (od C++11)

Type requirements

InputItLegacyInputIterator
OutputItLegacyOutputIterator
ForwardIt1
ForwardIt2
LegacyForwardIterator
UnaryPredicatePredicate

Return value

Output iterator to the element in the destination range, one past the last element copied.

Complexity

Exactly last - first applications of the predicate, between 0 and last - first assignments (assignment for every element for which predicate is equal to true).

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 ExecutionPolicy is one of the standard policies, std::terminate is called. For none other ExecutionPolicy, the behavior is implementation-defined.
  • If the algorithm fails to allocate memory, std::bad_alloc is thrown.

Possible implementation

copy_if (1)
template<class InputIt, class OutputIt, class UnaryPredicate>
OutputIt copy_if(InputIt first, InputIt last,
OutputIt d_first, UnaryPredicate pred)
{
for (; first != last; ++first)
{
if (pred(*first))
{
*d_first = *first;
++d_first;
}
}

return d_first;
}

Notes

In practice, implementations of std::copy_if avoid multiple assignments and use bulk copy_if functions such as std::memmove if the value type is TriviallyCopyable and the iterator types satisfy LegacyContiguousIterator.

When copy_ifing overlapping ranges, std::copy_if is appropriate when copy_ifing to the left (beginning of the destination range is outside the source range), while std::copy_if_backward is appropriate when copy_ifing to the right (end of the destination range is outside the source range).

Examples

Main.cpp
#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_if(from_vector.begin(), from_vector.end(),
std::back_inserter(to_vector));
// or, alternatively,
// std::vector<int> to_vector(from_vector.size());
// std::copy_if(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_if(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_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_if(from_vector.begin(), from_vector.end(),
std::back_inserter(to_vector),
[](int x) { return x % 3 == 0; });

for (int x : to_vector)
std::cout << x << ' ';
std::cout << '\n';
}
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
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::copy_if() algorithm

// (1)
template< class InputIt, class OutputIt, class UnaryPredicate >
constexpr OutputIt copy_if( InputIt first, InputIt last,
OutputIt d_first,
UnaryPredicate pred );

// (2)
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2, class UnaryPredicate >
ForwardIt2 copy_if( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first,
UnaryPredicate pred );

Copies the elements in the range, defined by [first; last), to another range beginning at d_first.

  • (1) Only copies the elements for which the predicate pred returns true.

    Undefined Behaviour

    The behavior is undefined if d_first is within the range [first; last).

  • (2) Same as (1), but executed according to policy.

Overload Resolution

These overloads participate in overload resolution only if std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>  (do C++20) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>  (od C++20) is true.

Parameters

first
second

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 true for the required elements.

The expression p(v) must be convertible to bool for every argument v of type (possibly const) VT, where VT is the value type of InputIt, regardless of value category, and must not modify v. Thus, a parameter type of VT& is not allowed , nor is VT unless for VT a move is equivalent to a copy. (od C++11)

Type requirements

InputItLegacyInputIterator
OutputItLegacyOutputIterator
ForwardIt1
ForwardIt2
LegacyForwardIterator
UnaryPredicatePredicate

Return value

Output iterator to the element in the destination range, one past the last element copied.

Complexity

Exactly last - first applications of the predicate, between 0 and last - first assignments (assignment for every element for which predicate is equal to true).

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 ExecutionPolicy is one of the standard policies, std::terminate is called. For none other ExecutionPolicy, the behavior is implementation-defined.
  • If the algorithm fails to allocate memory, std::bad_alloc is thrown.

Possible implementation

copy_if (1)
template<class InputIt, class OutputIt, class UnaryPredicate>
OutputIt copy_if(InputIt first, InputIt last,
OutputIt d_first, UnaryPredicate pred)
{
for (; first != last; ++first)
{
if (pred(*first))
{
*d_first = *first;
++d_first;
}
}

return d_first;
}

Notes

In practice, implementations of std::copy_if avoid multiple assignments and use bulk copy_if functions such as std::memmove if the value type is TriviallyCopyable and the iterator types satisfy LegacyContiguousIterator.

When copy_ifing overlapping ranges, std::copy_if is appropriate when copy_ifing to the left (beginning of the destination range is outside the source range), while std::copy_if_backward is appropriate when copy_ifing to the right (end of the destination range is outside the source range).

Examples

Main.cpp
#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_if(from_vector.begin(), from_vector.end(),
std::back_inserter(to_vector));
// or, alternatively,
// std::vector<int> to_vector(from_vector.size());
// std::copy_if(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_if(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_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_if(from_vector.begin(), from_vector.end(),
std::back_inserter(to_vector),
[](int x) { return x % 3 == 0; });

for (int x : to_vector)
std::cout << x << ' ';
std::cout << '\n';
}
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
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.