• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

    最終更新日時(UTC):
    が更新

    履歴 編集

    function template
    <random>

    std::generate_random

    namespace std::ranges {
      template <class R, class G>
        requires output_range<R, invoke_result_t<G&>> &&
                 uniform_random_bit_generator<remove_cvref_t<G>>
      constexpr borrowed_iterator_t<R>
        generate_random(R&& r, G&& g);                  // (1) C++26
    
      template <class G,
                output_iterator<invoke_result_t<G&>> O,
                sentinel_for<O> S>
        requires uniform_random_bit_generator<remove_cvref_t<G>>
      constexpr O
        generate_random(O first, S last, G&& g);        // (2) C++26
    
      template <class R, class G, class D>
        requires output_range<R, invoke_result_t<D&, G&>> &&
                 invocable<D&, G&> &&
                 uniform_random_bit_generator<remove_cvref_t<G>>
      constexpr borrowed_iterator_t<R>
        generate_random(R&& r, G&& g, D&& d);           // (3) C++26
    
      template <class G,
                class D,
                output_iterator<invoke_result_t<D&, G&>> O,
                sentinel_for<O> S>
        requires invocable<D&, G&> &&
                 uniform_random_bit_generator<remove_cvref_t<G>>
      constexpr O
        generate_random(O first, S last, G&& g, D&& d); // (4) C++26
    }
    

    概要

    乱数列を生成する。

    • (1) : 出力範囲rの各要素に、乱数生成器gで生成した乱数を代入する
    • (2) : 出力イテレータ範囲[first, last)の各要素に、乱数生成器gで生成した乱数を代入する
    • (3) : 出力範囲rの各要素に、乱数生成器gと分布生成器dで生成した乱数を代入する
    • (4) : 出力イテレータ範囲[first, last)の各要素に、乱数生成器gと分布生成器dで生成した乱数を代入する

    この関数は、for文を使用した以下のコードをアルゴリズム関数化したものである。

    std::vector<int> v(10);
    std::mt19937 gen {std::random_device{}()};
    std::uniform_int_distribution<int> dist{1, 100};
    
    // 以下の3つのコードは等価
    std::ranges::generate_random(v, gen);                  // (1)
    std::ranges::generate_random(v.begin(), v.end(), gen); // (2)
    for (auto& x : v) {
      x = gen();
    }
    
    // 以下の3つのコードは等価
    std::ranges::generate_random(v, gen, dist);                  // (3)
    std::ranges::generate_random(v.begin(), v.end(), gen, dist); // (4)
    for (auto& x : v) {
      x = dist(gen);
    }
    

    効果

    • (1) :

      • g.generate_random(std::forward<R>(r))が妥当な式であれば、それを呼び出す
        • 備考 : 乱数生成器がgenerate_random()メンバ関数をもっていればそれを使用する
      • そうでなく、Rsized_rangeのモデルである場合、値Nspan<invoke_result_t<G&>, N>型オブジェクトsに対して、式g()またはg.generate_random(s)未規定の回数だけ呼び出して実行し、rの各要素に代入する
        • 備考 : ここでのNは乱数生成の回数と異なってもよい
      • そうでなければ、ranges::generate(std::forward<R>(r), ref(g))を呼び出す
        • 備考 : std::forward_listのようなsize()メンバ関数をもたないコンテナがこちらに該当する
    • (2) : 以下と等価

      return generate_random(subrange<O, S>(std::move(first), last), g);
      

    • (3) :

      • d.generate_random(std::forward<R>(r), g)が妥当な式であれば、それを呼び出す
        • 備考 : 分布生成器がgenerate_random()メンバ関数をもっていればそれを使用する
      • そうでなく、Rsized_rangeのモデルである場合、値Nspan<invoke_result_t<D&, G&>, N>型オブジェクトsに対して、式invoke(d, g)またはd.generate_random(s, g)未規定の回数だけ呼び出して実行し、rの各要素に代入する
        • 備考 : ここでのNは乱数生成の回数と異なってもよい
      • そうでなければ、ranges::generate(std::forward<R>(r), [&d, &g] { return invoke(d, g); })を呼び出す
        • 備考 : std::forward_listのようなsize()メンバ関数をもたないコンテナがこちらに該当する
    • (4) : 以下と等価

      return generate_random(subrange<O, S>(std::move(first), last), g, d);
      

    戻り値

    #include <random>
    #include <print>
    #include <vector>
    
    int main()
    {
      std::random_device seed_gen;
      std::mt19937 engine(seed_gen());
      std::uniform_int_distribution<int> dist{0, 100};
    
      std::vector<int> v(10);
    
      // コンテナの全要素を乱数で埋める
      std::ranges::generate_random(v, engine);
      std::println("{}", v);
    
      // コンテナの全要素を、指定した分布の乱数で埋める
      std::ranges::generate_random(v, engine, dist);
      std::println("{}", v);
    }
    

    出力例

    [2034091041, 1919373608, 514210727, -1154669807, -315048337, -1224623446, -1986406128, -1034429876, -844125616, 1858136340]
    [83, 25, 48, 15, 9, 60, 47, 31, 91, 54]
    

    バージョン

    言語

    • C++26

    処理系

    参照