Spec-Zone.ru › C++

std::generate_n

Определён в заголовке <algorithm>
template< class OutputIt, class Size, class Generator >
OutputIt generate_n( OutputIt first, Size count, Generator g );
(1) (constexpr с C++20)
template< class ExecutionPolicy,
          class ForwardIt, class Size, class Generator >
ForwardIt generate_n( ExecutionPolicy&& policy,
                      ForwardIt first, Size count, Generator g );
(2) (с C++17)
1) Присваивает значения, сгенерированные заданным функциональным объектом g, первым count элементам диапазона, начинающегося с first, если count > 0. В противном случае ничего не делает.
2) Аналогично (1), но выполняется согласно policy.
Эта перегрузка участвует в разрешении перегрузки, только если значение следующего выражения равно true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(до C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(начиная с C++20)

Если Size не является преобразуемым к целочисленному типу, программа некорректна.

Параметры

first - начало диапазона элементов для генерации
count - количество генерируемых элементов
policy - политика выполнения
g - функциональный объект-генератор, который будет вызван.

Сигнатура функции должна быть эквивалентна следующей:

Ret fun();

Тип Ret должен обеспечивать возможность разыменования объекта типа OutputIt и присваивания ему значения типа Ret. ​

Требования к типам
-OutputIt должен соответствовать требованиям LegacyOutputIterator.
-ForwardIt должен соответствовать требованиям LegacyForwardIterator.

Возвращаемое значение

Итератор, следующий за последним присвоенным элементом, если count > 0, в противном случае — first.

Сложность

Ровно std::max(0, count) вызовов g() и операций присваивания.

Исключения

Перегрузка с параметром шаблона с именем ExecutionPolicy сообщает об ошибках следующим образом:

  • Если выполнение функции, вызванной в рамках алгоритма, выбрасывает исключение, а ExecutionPolicy является одной из стандартных политик, вызывается std::terminate. Для любого другого значения ExecutionPolicy поведение определяется реализацией.
  • Если алгоритму не удаётся выделить память, выбрасывается std::bad_alloc.

Возможная реализация

template<class OutputIt, class Size, class Generator>
constexpr // since C++20
OutputIt generate_n(OutputIt first, Size count, Generator g)
{
    for (Size i = 0; i < count; ++i, ++first)
        *first = g();
    
    return first;
}

Пример

#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <random>

int main()
{
    std::mt19937 rng; // default constructed, seeded with fixed seed
    std::generate_n(std::ostream_iterator<std::mt19937::result_type>(std::cout, " "),
                    5, std::ref(rng));
    std::cout << '\n';
}

Вывод:

3499211612 581869302 3890346734 3586334585 545404204

Отчёты об ошибках

Следующие отчёты об ошибках, изменяющие поведение, были применены ретроспективно к ранее опубликованным стандартам C++.

DR Применён к Опубликованное поведение Корректное поведение
LWG 426 C++98 требование к сложности гласило: «ровно count вызовов
или операций присваивания», что неверно, если count отрицательно
ни одного вызова или операции присваивания,
если count неположительно
LWG 865 C++98 позиция первого элемента после
диапазона генерации не возвращалась
возвращается

См. также

fill_n
копирует и присваивает заданное значение N элементам диапазона
(шаблон функции и функциональный объект алгоритма)
ranges::fill_n
(C++20)
generate
присваивает результаты последовательных вызовов функции каждому элементу диапазона
(шаблон функции и функциональный объект алгоритма)
ranges::generate
(C++20)
ranges::generate_n
(C++20)
сохраняет результат N применений функции
(функциональный объект алгоритма)

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

Spec-Zone.ru

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