Пространства имён
Варианты
Действия

std::copy, std::copy_if

Материал из cppreference.com
< cpp‎ | algorithm
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы над диапазонами (C++20)
Ограниченные алгоритмы, например ranges::copy, ranges::sort, ...
Политики исполнения (C++17)
Немодифицирующие операции над последовательностями
(C++11)(C++11)(C++11)
(C++17)
Модифицирующие операции над последовательностями
copycopy_if
(C++11)
(C++11)
(C++11)
(C++20)(C++20)
Операции разбиения
Операции сортировки
(C++11)
Операции двоичного поиска
Операции с наборами (в отсортированных диапазонах)
Операции с кучей
(C++11)
Операций минимума/максимума
(C++11)
(C++17)

Операции перестановки
Числовые операции
Операции с неинициализированной памятью
(C++17)
(C++17)
(C++17)
Библиотека C
 
Определено в заголовочном файле <algorithm>
template< class InputIt, class OutputIt >
OutputIt copy( InputIt first, InputIt last, OutputIt d_first );
(1)
template< class InputIt, class OutputIt, class UnaryPredicate >

OutputIt copy_if( InputIt first, InputIt last,
                  OutputIt d_first,

                  UnaryPredicate pred );
(2) (начиная с C++11)

Копирует элементы диапазона [firstlast) в диапазон, начинающийся с d_first. Второй вариант копирует только те элементы, для которых предикат pred возвращает true.

Содержание

[править] Параметры

[firstlast) два итератора задающих диапазон элементов для копирования
d_first Начало целевого диапазона. Если Шаблон:с находится внутри [firstlast), вместо std::copy нужно использовать std::copy_backward
pred унарный предикат, который возвращает​true для соответствующих элементов.

Определение функции предиката должно быть эквивалентно следующему:

 bool pred(const Type &a);

Присутствие const & в определении не обязательно, но функция не должна модифицировать передаваемые ей объекты.
Тип Type должен быть таков, что объект типа InputIt может быть разыменован и затем неявно преобразован в Type. ​

Требования к типам
-
InputIt должен соответствовать требованиям InputIterator.
-
OutputIt должен соответствовать требованиям OutputIterator.

[править] Возвращаемое значение

Output-итератор на элемент в целевом диапазоне, следующий сразу за последним скопированным элементом.

[править] Сложность

1) Ровно last - first присваиваний.

2) Ровно last - first применений предиката и не более last - first присваиваний.

[править] Примечания

На практике, если тип элементов диапазона является TriviallyCopyable, в реализации функции std::copy используется не оператор присваивания, а функция массового копирования, такая как std::memcpy.

[править] Возможная реализация

Первый вариант
template<class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last,
              OutputIt d_first)
{
    while (first != last) {
        *d_first++ = *first++;
    }
    return d_first;
}
Второй вариант
template<class InputIt, class OutputIt, class UnaryPredicate>
OutputIt copy_if(InputIt first, InputIt last,
                 OutputIt d_first, UnaryPredicate pred)
{
    while (first != last) {
        if(pred(*first))
            *d_first++ = *first;
        first++;
    }
    return d_first;
}

[править] Пример

Следующая программа использует функцию std::copy как для копирования содержания одного вектора в другой, так и для вывода на экран результирующего вектора:

#include <algorithm>
#include <iostream>
#include <vector>
#include <iterator>
 
int main()
{
    std::vector<int> from_vector;
    for (int i = 0; i < 10; i++) {
        from_vector.push_back(i);
    }
 
    std::vector<int> to_vector(10);
 
    std::copy(from_vector.begin(), from_vector.end(), to_vector.begin());
 
    std::cout << "to_vector содержит: ";
    std::copy(to_vector.begin(), to_vector.end(),
              std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;
}

Вывод:

to_vector содержит: 0 1 2 3 4 5 6 7 8 9

[править] См. также

копирует диапазон элементов в обратном порядке
(шаблон функции) [править]
копирует диапазон элементов, исключая те, которые соответствуют определённым критериям
(шаблон функции) [править]