std:: copy, std:: copy_if
|
Определено в заголовке
<algorithm>
|
||
|
template
<
class
InputIt,
class
OutputIt
>
OutputIt copy
(
InputIt first, InputIt last,
|
(1) | (constexpr since C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt1,
class
ForwardIt2
>
|
(2) | (since C++17) |
|
template
<
class
InputIt,
class
OutputIt,
class
UnaryPred
>
OutputIt copy_if
(
InputIt first, InputIt last,
|
(3) |
(since C++11)
(constexpr since C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt1,
class
ForwardIt2,
class
UnaryPred
>
|
(4) | (since C++17) |
Копирует элементы в диапазоне, определённом
[
first
,
last
)
, в другой диапазон, начинающийся с
d_first
(диапазон назначения копирования).
[
first
,
last
)
начиная с
first
и продвигаясь к
last
.
[
first
,
last
)
, поведение не определено. В этом случае вместо этого может быть использована функция
std::copy_backward
.
|
std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> равно true . |
(до C++20) |
|
std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> равно true . |
(начиная с C++20) |
[
first
,
last
)
и диапазон назначения копирования перекрываются, поведение не определено.
[
first
,
last
)
и диапазон назначения копирования перекрываются, поведение не определено.
|
std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> равно true . |
(до C++20) |
|
std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> равно true . |
(начиная с C++20) |
Содержание |
Параметры
| first, last | - | пара итераторов, определяющих исходный диапазон элементов для копирования |
| d_first | - | начало диапазона назначения |
| policy | - | политика выполнения для использования |
| pred | - |
унарный предикат, который возвращает
true
для требуемых элементов.
Выражение
pred
(
v
)
должно быть преобразуемо в
bool
для каждого аргумента
|
| Требования к типам | ||
-
InputIt
должен удовлетворять требованиям
LegacyInputIterator
.
|
||
-
OutputIt
должен удовлетворять требованиям
LegacyOutputIterator
.
|
||
-
ForwardIt1, ForwardIt2
должен удовлетворять требованиям
LegacyForwardIterator
.
|
||
-
UnaryPred
должен удовлетворять требованиям
Predicate
.
|
||
Возвращаемое значение
Выходной итератор на элемент в целевом диапазоне, следующий за последним скопированным элементом.
Сложность
Дано N как std:: distance ( first, last ) :
Для перегрузок с
ExecutionPolicy
может возникнуть снижение производительности, если тип значения
ForwardIt1
не является
MoveConstructible
.
Исключения
Перегрузки с параметром шаблона с именем
ExecutionPolicy
сообщают об ошибках следующим образом:
-
Если выполнение функции, вызванной как часть алгоритма, выбрасывает исключение и
ExecutionPolicyявляется одним из стандартных политик , std::terminate вызывается. Для любой другойExecutionPolicyповедение определяется реализацией. - Если алгоритму не удается выделить память, std::bad_alloc выбрасывается.
Возможная реализация
| 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; } |
Примечания
На практике реализации
std::copy
избегают множественных присваиваний и используют функции массового копирования, такие как
std::memmove
, если тип значения является
TriviallyCopyable
и типы итераторов удовлетворяют требованиям
LegacyContiguousIterator
.
При копировании перекрывающихся диапазонов,
std::copy
следует использовать при копировании влево (начало целевого диапазона находится вне исходного диапазона), тогда как
std::copy_backward
следует использовать при копировании вправо (конец целевого диапазона находится вне исходного диапазона).
Пример
Следующий код использует
std::copy
как для копирования содержимого одного
std::vector
в другой, так и для отображения результирующего
std::vector
.
#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)); // или, альтернативно, // std::vector<int> to_vector(from_vector.size()); // std::copy(from_vector.begin(), from_vector.end(), to_vector.begin()); // любой способ эквивалентен // 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'; }
Возможный вывод:
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
Отчёты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| 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 |
Смотрите также
|
копирует диапазон элементов в обратном порядке
(шаблон функции) |
|
|
создаёт копию диапазона в обратном порядке
(шаблон функции) |
|
|
(C++11)
|
копирует указанное количество элементов в новое место
(шаблон функции) |
|
присваивает заданное значение каждому элементу диапазона
(шаблон функции) |
|
|
копирует диапазон элементов, исключая те, которые удовлетворяют определённым критериям
(шаблон функции) |
|
|
(C++20)
(C++20)
|
копирует диапазон элементов в новое место
(функциональный объект алгоритма) |