Spec-Zone.ru › C++

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> n, O result );
(1) (с C++20)
Вспомогательный тип
template< class I, class O >
using copy_n_result = ranges::in_out_result<I, O>;
(2) (с C++20)
1) Копирует ровно n элементов из диапазона, начинающегося в first, в диапазон, начинающийся в result, выполняя *(result + i) = *(first + i) для каждого целого числа в [​0​, n). Поведение не определено, если result находится в диапазоне [first, first + n) (в этом случае может быть использован ranges::copy_backward).

Функциональные сущности, описанные на этой странице, являются niebloids, то есть:

  • Явные списки аргументов шаблонов не могут быть указаны при вызове ни одной из них.
  • Ни одна из них не видна для поиска аргументов.
  • При обнаружении любой из них с помощью обычного неквалифицированного поиска в качестве имени слева от оператора вызова функции, поиск аргументов подавляется.

На практике они могут быть реализованы как объекты функций или с помощью специальных расширений компилятора.

Параметры

first - начало диапазона элементов, которые нужно скопировать
n - количество элементов для копирования
result - начало целевого диапазона

Значение возврата

ranges::copy_n_result{first + n, result + n} или, более формально, значение типа ranges::in_out_result, содержащее итератор std::input_iterator равный ranges::next(first, n) и итератор std::weakly_incrementable равный ranges::next(result, n).

Сложность

Ровно n присваиваний.

Примечания

На практике реализации std::ranges::copy_n могут избегать множественных присваиваний и использовать функции массовой копирования, такие как std::memmove, если тип значения является TriviallyCopyable, а типы итераторов удовлетворяют contiguous_iterator. В качестве альтернативы такое ускорение копирования может быть внедрено на фазе оптимизации компилятора.

При копировании перекрывающихся диапазонов std::ranges::copy_n уместно при копировании влево (начало целевого диапазона находится вне исходного диапазона), а std::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 result) const
    {
        for (std::iter_difference_t<I> i {}; i != n; ++i, ++first, ++result)
            *result = *first;
        return {std::move(first), std::move(result)};
    }
};
 
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());
    std::cout
        << "*(res.in): '" << *(res.in) << "', distance: "
        << std::distance(std::begin(in), res.in) << '\n'
        << "*(res.out): '" << *(res.out) << "', distance: "
        << std::distance(std::begin(out), res.out) << '\n';
}

Вывод:

"ABCD"
*(res.in): 'F', distance: 5
*(res.out): 'f', distance: 5

См. также

ranges::copyranges::copy_if
(C++20)(C++20)
копирует диапазон элементов в новое местоположение
(niebloid)
ranges::copy_backward
(C++20)
копирует диапазон элементов в обратном порядке
(niebloid)
ranges::remove_copyranges::remove_copy_if
(C++20)(C++20)
копирует диапазон элементов, опуская те, которые удовлетворяют определенным критериям
(niebloid)
ranges::replace_copyranges::replace_copy_if
(C++20)(C++20)
копирует диапазон, заменяя элементы, удовлетворяющие определенным критериям, другим значением
(niebloid)
ranges::reverse_copy
(C++20)
создает копию диапазона, который перевернут
(niebloid)
ranges::rotate_copy
(C++20)
копирует и вращает диапазон элементов
(niebloid)
ranges::unique_copy
(C++20)
создает копию некоторого диапазона элементов, который не содержит последовательных дубликатов
(niebloid)
ranges::move
(C++20)
перемещает диапазон элементов в новое местоположение
(niebloid)
ranges::move_backward
(C++20)
перемещает диапазон элементов в новое местоположение в обратном порядке
(niebloid)
copy_n
(C++11)
копирует количество элементов в новое местоположение
(функция-шаблон)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/algorithm/ranges/copy_n

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API