std::ranges::copy_n, std::ranges::copy_n_result
Определён в заголовочном файле <algorithm> | ||
|---|---|---|
| Сигнатура вызова | ||
template< std::input_iterator I, std::weakly_incrementable O >
requires std::indirectly_copyable<I, O>
constexpr copy_n_result<I, O>
copy_n( I first, std::iter_difference_t<I> count, O d_first );
| (1) | (начиная с C++20) |
template< /*execution-policy*/ Ep, std::random_access_iterator I,
std::random_access_iterator O, std::sized_sentinel_for<O> OutS >
requires std::indirectly_copyable<I, O>
copy_n_result<I, O>
copy_n( Ep&& policy, I first, iter_difference_t<I> count,
O d_first, OutS d_last );
| (2) | (начиная с C++26) |
| Вспомогательный тип | ||
template< class I, class O > using copy_n_result = ranges::in_out_result<I, O>; | (3) | (начиная с C++20) |
Определение /*execution-policy*/ см. на этой странице.
Если count положительно, элементы исходного диапазона [first, ranges::next(first, count)) копируются в целевой диапазон. В противном случае функция ничего не делает.
[d_first, ranges::next(d_first, count)).policy, а целевой диапазон — [d_first, d_last). Если целевой диапазон закончится раньше, чем будет достигнут конец исходного диапазона, оставшиеся элементы исходного диапазона не будут скопированы.Описанные на этой странице функциональные объекты — это функциональные объекты алгоритмов (неофициально называемые niebloids), то есть:
- При вызове любого из них нельзя указать явный список аргументов шаблона.
- Ни один из них не виден для поиска, зависящего от аргументов.
- Если любой из них найден при помощи обычного неквалифицированного поиска как имя слева от оператора вызова функции, поиск, зависящий от аргументов, блокируется.
Параметры
| first | - | начало исходного диапазона |
| count | - | количество копируемых элементов |
| d_first | - | начало целевого диапазона |
| policy | - | используемая политика выполнения |
Возвращаемое значение
Объект ranges::copy_n_result, в котором:
- Поле данных
inсодержит итератор, указывающий на элемент, следующий за последним скопированным элементом исходного диапазона, или итератор на начало исходного диапазона, если ни один элемент не скопирован. - Поле данных
outсодержит итератор, указывающий на элемент, следующий за последним элементом целевого диапазона, в который было выполнено копирующее присваивание, или итератор на начало целевого диапазона, если ни один элемент не скопирован.
Сложность
Обозначим
- \(\scriptsize N_1\)N1 как \(\scriptsize \max(\mathtt{count},0)\)max(count,0), и
- \(\scriptsize N_2\)N2 как
ranges::distance(d_first, d_last):
Исключения
2) В процессе выполнения:- Если требуемые для распараллеливания временные ресурсы памяти недоступны, выбрасывается
std::bad_alloc. - Если при обращении к объектам через аргумент алгоритма выбрасывается неперехваченное исключение, поведение определяется политикой выполнения (для стандартных политик вызывается
std::terminate).
Примечания
На практике реализации ranges::copy_n могут избегать множественных операций присваивания и использовать функции массового копирования, такие как std::memmove, если тип значения является TriviallyCopyable, а типы итераторов удовлетворяют требованиям contiguous_iterator. Также такое ускорение копирования может быть добавлено на этапе оптимизации компилятора.
При копировании перекрывающихся диапазонов ranges::copy_n подходит для копирования влево (начало целевого диапазона находится вне исходного диапазона), а ranges::copy_backward — для копирования вправо (конец целевого диапазона находится вне исходного диапазона).
Возможная реализация
struct copy_n_fn
{
template<std::input_iterator I, std::weakly_incrementable O>
requires std::indirectly_copyable<I, O>
constexpr ranges::copy_n_result<I, O>
operator()(I first, std::iter_difference_t<I> n, O d_first) const
{
for (; n-- > 0; (void)++first, (void)++d_first)
*d_first = *first;
return {std::move(first), std::move(d_first)};
}
};
inline constexpr copy_n_fn copy_n{};
|
Пример
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <string>
#include <string_view>
int main()
{
const std::string_view in{"ABCDEFGH"};
std::string out;
std::ranges::copy_n(in.begin(), 4, std::back_inserter(out));
std::cout << std::quoted(out) << '\n';
out = "abcdefgh";
const auto res{std::ranges::copy_n(in.begin(), 5, out.begin())};
const auto i{std::distance(std::begin(in), res.in)};
const auto j{std::distance(std::begin(out), res.out)};
std::cout << "in[" << i << "] = '" << in[i] << "'\n"
<< "out[" << j << "] = '" << out[j] << "'\n";
}
Вывод:
"ABCD" in[5] = 'F' out[5] = 'f'
См. также
|
(C++11) | копирует заданное количество элементов в новое место (функция-шаблон) |
|
(C++20)(C++20) | копирует диапазон элементов в новое место (функциональный объект алгоритма) |
|
(C++20) | копирует диапазон элементов в обратном порядке (функциональный объект алгоритма) |
|
(C++20)(C++20) | копирует диапазон элементов, исключая те, которые удовлетворяют заданным условиям (функциональный объект алгоритма) |
|
(C++20)(C++20) | копирует диапазон, заменяя элементы, удовлетворяющие заданным условиям, другим значением (функциональный объект алгоритма) |
|
(C++20) | создаёт копию диапазона в обратном порядке (функциональный объект алгоритма) |
|
(C++20) | копирует и циклически сдвигает диапазон элементов (функциональный объект алгоритма) |
|
(C++20) | создаёт копию диапазона элементов без последовательных дубликатов (функциональный объект алгоритма) |
|
(C++20) | перемещает диапазон элементов в новое место (функциональный объект алгоритма) |
|
(C++20) | перемещает диапазон элементов в новое место в обратном порядке (функциональный объект алгоритма) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/ranges/copy_n