|
| 1 | +# generate_random |
| 2 | +* random[meta header] |
| 3 | +* std[meta namespace] |
| 4 | +* function template[meta id-type] |
| 5 | +* cpp26[meta cpp] |
| 6 | + |
| 7 | +```cpp |
| 8 | +namespace std::ranges { |
| 9 | + template <class R, class G> |
| 10 | + requires output_range<R, invoke_result_t<G&>> && |
| 11 | + uniform_random_bit_generator<remove_cvref_t<G>> |
| 12 | + constexpr borrowed_iterator_t<R> |
| 13 | + generate_random(R&& r, G&& g); // (1) C++26 |
| 14 | + |
| 15 | + template <class G, |
| 16 | + output_iterator<invoke_result_t<G&>> O, |
| 17 | + sentinel_for<O> S> |
| 18 | + requires uniform_random_bit_generator<remove_cvref_t<G>> |
| 19 | + constexpr O |
| 20 | + generate_random(O first, S last, G&& g); // (2) C++26 |
| 21 | + |
| 22 | + template <class R, class G, class D> |
| 23 | + requires output_range<R, invoke_result_t<D&, G&>> && |
| 24 | + invocable<D&, G&> && |
| 25 | + uniform_random_bit_generator<remove_cvref_t<G>> |
| 26 | + constexpr borrowed_iterator_t<R> |
| 27 | + generate_random(R&& r, G&& g, D&& d); // (3) C++26 |
| 28 | + |
| 29 | + template <class G, |
| 30 | + class D, |
| 31 | + output_iterator<invoke_result_t<D&, G&>> O, |
| 32 | + sentinel_for<O> S> |
| 33 | + requires invocable<D&, G&> && |
| 34 | + uniform_random_bit_generator<remove_cvref_t<G>> |
| 35 | + constexpr O |
| 36 | + generate_random(O first, S last, G&& g, D&& d); // (4) C++26 |
| 37 | +} |
| 38 | +``` |
| 39 | +* output_range[link /reference/ranges/output_range.md] |
| 40 | +* uniform_random_bit_generator[link uniform_random_bit_generator.md] |
| 41 | +* invoke_result_t[link /reference/type_traits/invoke_result.md] |
| 42 | +* remove_cvref_t[link /reference/type_traits/remove_cvref.md] |
| 43 | +* borrowed_iterator_t[link /reference/ranges/borrowed_iterator_t.md] |
| 44 | +* output_iterator[link /reference/iterator/output_iterator.md] |
| 45 | +* sentinel_for[link /reference/iterator/sentinel_for.md] |
| 46 | +* invocable[link /reference/concepts/invocable.md] |
| 47 | +
|
| 48 | +## 概要 |
| 49 | +乱数列を生成する。 |
| 50 | +
|
| 51 | +- (1) : 出力範囲`r`の各要素に、乱数生成器`g`で生成した乱数を代入する |
| 52 | +- (2) : 出力イテレータ範囲`[first, last)`の各要素に、乱数生成器`g`で生成した乱数を代入する |
| 53 | +- (3) : 出力範囲`r`の各要素に、乱数生成器`g`と分布生成器`d`で生成した乱数を代入する |
| 54 | +- (4) : 出力イテレータ範囲`[first, last)`の各要素に、乱数生成器`g`と分布生成器`d`で生成した乱数を代入する |
| 55 | +
|
| 56 | +この関数は、`for`文を使用した以下のコードをアルゴリズム関数化したものである。 |
| 57 | +
|
| 58 | +```cpp |
| 59 | +std::vector<int> v(10); |
| 60 | +std::mt19937 gen {std::random_device{}()}; |
| 61 | +std::uniform_int_distribution<int> dist{1, 100}; |
| 62 | +
|
| 63 | +// 以下の3つのコードは等価 |
| 64 | +std::ranges::generate_random(v, gen); // (1) |
| 65 | +std::ranges::generate_random(v.begin(), v.end(), gen); // (2) |
| 66 | +for (auto& x : v) { |
| 67 | + x = gen(); |
| 68 | +} |
| 69 | +
|
| 70 | +// 以下の3つのコードは等価 |
| 71 | +std::ranges::generate_random(v, gen, dist); // (3) |
| 72 | +std::ranges::generate_random(v.begin(), v.end(), gen, dist); // (4) |
| 73 | +for (auto& x : v) { |
| 74 | + x = dist(gen); |
| 75 | +} |
| 76 | +``` |
| 77 | + |
| 78 | + |
| 79 | +## 効果 |
| 80 | +- (1) : |
| 81 | + - `g.generate_random(`[`std::forward`](/reference/utility/forward.md)`<R>(r))`が妥当な式であれば、それを呼び出す |
| 82 | + - 備考 : 乱数生成器が`generate_random()`メンバ関数をもっていればそれを使用する |
| 83 | + - そうでなく、`R`が[`sized_range`](/reference/ranges/sized_range.md)のモデルである場合、値`N`と[`span`](/reference/span/span.md)`<`[`invoke_result_t`](/reference/type_traits/invoke_result.md)`<G&>, N>`型オブジェクト`s`に対して、式`g()`または`g.generate_random(s)`を未規定の回数だけ呼び出して実行し、`r`の各要素に代入する |
| 84 | + - 備考 : ここでの`N`は乱数生成の回数と異なってもよい |
| 85 | + - そうでなければ、[`ranges::generate`](/reference/algorithm/ranges_generate.md)`(`[`std::forward`](/reference/utility/forward.md)`<R>(r), ref(g))`を呼び出す |
| 86 | + - 備考 : [`std::forward_list`](/reference/forward_list/forward_list.md)のような`size()`メンバ関数をもたないコンテナがこちらに該当する |
| 87 | + |
| 88 | +- (2) : 以下と等価 |
| 89 | + ```cpp |
| 90 | + return generate_random(subrange<O, S>(std::move(first), last), g); |
| 91 | + ``` |
| 92 | + * subrange[link /reference/ranges/subrange.md] |
| 93 | + * std::move[link /reference/utility/move.md] |
| 94 | + |
| 95 | +- (3) : |
| 96 | + - `d.generate_random(`[`std::forward`](/reference/utility/forward.md)`<R>(r), g)`が妥当な式であれば、それを呼び出す |
| 97 | + - 備考 : 分布生成器が`generate_random()`メンバ関数をもっていればそれを使用する |
| 98 | + - そうでなく、`R`が[`sized_range`](/reference/ranges/sized_range.md)のモデルである場合、値`N`と[`span`](/reference/span/span.md)`<`[`invoke_result_t`](/reference/type_traits/invoke_result.md)`<D&, G&>, N>`型オブジェクト`s`に対して、式[`invoke`](/reference/functional/invoke.md)`(d, g)`または`d.generate_random(s, g)`を未規定の回数だけ呼び出して実行し、`r`の各要素に代入する |
| 99 | + - 備考 : ここでの`N`は乱数生成の回数と異なってもよい |
| 100 | + - そうでなければ、[`ranges::generate`](/reference/algorithm/ranges_generate.md)`(`[`std::forward`](/reference/utility/forward.md)`<R>(r), [&d, &g] { return` [`invoke`](/reference/functional/invoke.md)`(d, g); })`を呼び出す |
| 101 | + - 備考 : [`std::forward_list`](/reference/forward_list/forward_list.md)のような`size()`メンバ関数をもたないコンテナがこちらに該当する |
| 102 | + |
| 103 | +- (4) : 以下と等価 |
| 104 | + ```cpp |
| 105 | + return generate_random(subrange<O, S>(std::move(first), last), g, d); |
| 106 | + ``` |
| 107 | + * subrange[link /reference/ranges/subrange.md] |
| 108 | + * std::move[link /reference/utility/move.md] |
| 109 | + |
| 110 | + |
| 111 | +## 戻り値 |
| 112 | +- (1), (3) : |
| 113 | + ```cpp |
| 114 | + return ranges::end(r); |
| 115 | + ``` |
| 116 | + * ranges::end[link /reference/ranges/end.md] |
| 117 | + |
| 118 | + |
| 119 | +## 例 |
| 120 | +```cpp example |
| 121 | +#include <random> |
| 122 | +#include <print> |
| 123 | +#include <vector> |
| 124 | + |
| 125 | +int main() |
| 126 | +{ |
| 127 | + std::random_device seed_gen; |
| 128 | + std::mt19937 engine(seed_gen()); |
| 129 | + std::uniform_int_distribution<int> dist{0, 100}; |
| 130 | + |
| 131 | + std::vector<int> v(10); |
| 132 | + |
| 133 | + // コンテナの全要素を乱数で埋める |
| 134 | + std::ranges::generate_random(v, engine); |
| 135 | + std::println("{}", v); |
| 136 | + |
| 137 | + // コンテナの全要素を、指定した分布の乱数で埋める |
| 138 | + std::ranges::generate_random(v, engine, dist); |
| 139 | + std::println("{}", v); |
| 140 | +} |
| 141 | +``` |
| 142 | +* std::generate_canonical[color ff0000] |
| 143 | +* digits[link /reference/limits/numeric_limits/digits.md] |
| 144 | + |
| 145 | +### 出力 |
| 146 | +``` |
| 147 | +[2034091041, 1919373608, 514210727, -1154669807, -315048337, -1224623446, -1986406128, -1034429876, -844125616, 1858136340] |
| 148 | +[83, 25, 48, 15, 9, 60, 47, 31, 91, 54] |
| 149 | +``` |
| 150 | + |
| 151 | +## バージョン |
| 152 | +### 言語 |
| 153 | +- C++26 |
| 154 | + |
| 155 | +### 処理系 |
| 156 | +- [Clang](/implementation.md#clang): 19.0 [mark noimpl] |
| 157 | +- [GCC](/implementation.md#gcc): 14 [mark noimpl] |
| 158 | +- [Visual C++](/implementation.md#visual_cpp): 2022 Update 10 [mark noimpl] |
| 159 | + |
| 160 | + |
| 161 | +## 参照 |
| 162 | +- [P1068R11 Vector API for random number generation](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p1068r11.pdf) |
0 commit comments