跳到主要内容

std::ranges::generate() 算法

// (1)
constexpr O generate( O first, S last, F gen );

// (2)
constexpr ranges::borrowed_iterator_t<R> generate( R&& r, F gen );

参数类型是泛型的,并具有以下约束:

  • O - std::input_or_output_iterator
  • S - std::sentinel_for<O>
  • R - (无)
  • F - std::copy_constructible

此外,每个重载都有以下约束

  • (1) - invocable<F&> && indirectly_writable<O, invoke_result_t<F&>>
  • (1) - invocable<F&> && ranges::output_range<R, invoke_result_t<F&>>

(为方便阅读,此处省略了 std:: 命名空间)

  • (1) 将函数对象 gen 的连续调用结果赋给范围 [first; last) 中的每个元素。

  • (2)(2) 相同,但使用 r 作为第一个源范围,如同使用 ranges::begin(r) 作为 firstranges::end(r) 作为 last

本页描述的函数类实体是niebloids

参数

first
last

要修改的元素范围。

r

要修改的元素范围。

gen

生成器函数对象。

返回值

一个输出迭代器,与 last 比较相等。

复杂度

精确地调用 gen() 和赋值 ranges::distance(first, last) 次。

异常

(无)

可能的实现

generate(1) 和 generate(2)
struct generate_fn
{
template<std::input_or_output_iterator O, std::sentinel_for<O> S,
std::copy_constructible F>
requires std::invocable<F&> && std::indirectly_writable<O, std::invoke_result_t<F&>>
constexpr O operator()(O first, S last, F gen) const
{
for (; first != last; *first = std::invoke(gen), ++first)
{}
return first;
}

template<class R, std::copy_constructible F>
requires std::invocable<F&> && ranges::output_range<R, std::invoke_result_t<F&>>
constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, F gen) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(gen));
}
};

inline constexpr generate_fn generate {};

示例

Main.cpp
#include <algorithm>
#include <array>
#include <iostream>
#include <random>
#include <string_view>

auto dice()
{
static std::uniform_int_distribution<int> distr {1, 6};
static std::random_device device;
static std::mt19937 engine {device()};
return distr(engine);
}

void iota(auto& v, int n)
{
std::ranges::generate(v, [&n]() mutable { return n++; });
}

void print(std::string_view comment, const auto& v)
{
for (std::cout << comment; int i : v)
std::cout << i << ' ';
std::cout << '\n';
}

int main()
{
std::array<int, 8> v;

std::ranges::generate(v.begin(), v.end(), dice);
print("dice: ", v);
std::ranges::generate(v, dice);
print("dice: ", v);

iota(v, 1);
print("iota: ", v);
}
输出
dice: 4 3 1 6 6 4 5 5
dice: 4 2 5 3 6 2 6 2
iota: 1 2 3 4 5 6 7 8
本文来源于此 CppReference 页面。它可能为了改进或编辑者的偏好而进行了修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。

std::ranges::generate() 算法

// (1)
constexpr O generate( O first, S last, F gen );

// (2)
constexpr ranges::borrowed_iterator_t<R> generate( R&& r, F gen );

参数类型是泛型的,并具有以下约束:

  • O - std::input_or_output_iterator
  • S - std::sentinel_for<O>
  • R - (无)
  • F - std::copy_constructible

此外,每个重载都有以下约束

  • (1) - invocable<F&> && indirectly_writable<O, invoke_result_t<F&>>
  • (1) - invocable<F&> && ranges::output_range<R, invoke_result_t<F&>>

(为方便阅读,此处省略了 std:: 命名空间)

  • (1) 将函数对象 gen 的连续调用结果赋给范围 [first; last) 中的每个元素。

  • (2)(2) 相同,但使用 r 作为第一个源范围,如同使用 ranges::begin(r) 作为 firstranges::end(r) 作为 last

本页描述的函数类实体是niebloids

参数

first
last

要修改的元素范围。

r

要修改的元素范围。

gen

生成器函数对象。

返回值

一个输出迭代器,与 last 比较相等。

复杂度

精确地调用 gen() 和赋值 ranges::distance(first, last) 次。

异常

(无)

可能的实现

generate(1) 和 generate(2)
struct generate_fn
{
template<std::input_or_output_iterator O, std::sentinel_for<O> S,
std::copy_constructible F>
requires std::invocable<F&> && std::indirectly_writable<O, std::invoke_result_t<F&>>
constexpr O operator()(O first, S last, F gen) const
{
for (; first != last; *first = std::invoke(gen), ++first)
{}
return first;
}

template<class R, std::copy_constructible F>
requires std::invocable<F&> && ranges::output_range<R, std::invoke_result_t<F&>>
constexpr ranges::borrowed_iterator_t<R> operator()(R&& r, F gen) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(gen));
}
};

inline constexpr generate_fn generate {};

示例

Main.cpp
#include <algorithm>
#include <array>
#include <iostream>
#include <random>
#include <string_view>

auto dice()
{
static std::uniform_int_distribution<int> distr {1, 6};
static std::random_device device;
static std::mt19937 engine {device()};
return distr(engine);
}

void iota(auto& v, int n)
{
std::ranges::generate(v, [&n]() mutable { return n++; });
}

void print(std::string_view comment, const auto& v)
{
for (std::cout << comment; int i : v)
std::cout << i << ' ';
std::cout << '\n';
}

int main()
{
std::array<int, 8> v;

std::ranges::generate(v.begin(), v.end(), dice);
print("dice: ", v);
std::ranges::generate(v, dice);
print("dice: ", v);

iota(v, 1);
print("iota: ", v);
}
输出
dice: 4 3 1 6 6 4 5 5
dice: 4 2 5 3 6 2 6 2
iota: 1 2 3 4 5 6 7 8
本文来源于此 CppReference 页面。它可能为了改进或编辑者的偏好而进行了修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。