This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4289. Seed sequence is overspecified

Section: 29.5.3.2 [rand.req.seedseq] Status: New Submitter: Magnus Fromreide Opened: 2025-06-22 Last modified: 2025-07-06

Priority: Not Prioritized

View all other issues in [rand.req.seedseq].

View all issues with New status.

Discussion:

The requirements on a seed sequence are so strict that it is forbidden to initialize a random number generator directly from a hardware random number generator without lots of boiler plate and intermediary objects.

The main problem is that the seed sequence requirements state that a seed sequence must be "kind of copyable" and that calls to the copy must generate the same output as calls to the original.

If one checks the uses of seed sequences then nothing makes use of this capability so I propose to just drop it.

There has been a previous attempt to handle this issue using P0205 which preserved the old seed sequence and added a new concept that it used to seed generators. That effort stalled with the comment that it should be solved without the new std::seed_adapter. This DR sidesteps that whole issue by simply removing the unused requirements from the seed sequence concept.

I will admit that I am unsure about the deletion of Note 1 but since it only seems to attempt to motivate the copyability I opted to let it go along with the requirements.

Proposed resolution:

This wording is relative to N5008.

  1. Modify 29.5.3.2 [rand.req.seedseq] as indicated:

    -1- A seed sequence is an object that consumes a sequence of integer-valued data and produces a requested number of unsigned integer values i, 0 = i < 232, based on the consumed data.

    [Note 1: Such an object provides a mechanism to avoid replication of streams of random variates. This can be useful, for example, in applications requiring large numbers of random number engines. — end note]

    -2- A class S meets the requirements of a seed sequence if the expressions shown in Table 124 [tab:rand.req.seedseq] are valid and have the indicated semantics, and if S also meets all other requirements of 29.5.3.2 [rand.req.seedseq]. In Table 124 [tab:rand.req.seedseq] and throughout this subclause:

    1. (2.1) — T is the type named by S' s associated result_type;

    2. (2.2) — q is a value of type S and r is a value of type S or const S; and

    3. (2.3) — ib and ie are input iterators with an unsigned integer value_type of at least 32 bits;

    4. (2.4) — rb and re are mutable random access iterators with an unsigned integer value_type of at least 32 bits;.

    5. (2.5) — ob is an output iterator; and

    6. (2.6) — il is a value of type initializer_list<T>.

    Table 124 — Seed sequence requirements [tab:rand.req.seedseq]
    Expression Return type Pre/post-condition Complexity
    S::result_type T T is an unsigned integer
    type (6.8.2 [basic.fundamental]) of at least 32 bits.
    S() Creates a seed sequence with
    the same initial state as all
    other default-constructed seed
    sequences of type S.
    constant
    S(ib,ie) Creates a seed sequence having
    internal state that depends on
    some or all of the bits of the
    supplied sequence [ib, ie).
    𝒪(ie - ib)
    S(il) Same as S(il.begin(), il.end()). same as S(il.begin(), il.end())
    q.generate(rb,re) void Does nothing if rb == re.
    Otherwise, fills the supplied
    sequence [rb, re) with 32-bit
    quantities that depend on the
    sequence supplied to the
    constructor and possibly also
    depend on the history of
    generate's previous
    invocations.
    𝒪(re - rb)
    r.size() size_t The number of 32-bit units that
    would be copied by a call to
    r.param.
    constant
    r.param(ob) void Copies to the given destination
    a sequence of 32-bit units that
    can be provided to the
    constructor of a second object of
    type S, and that would
    reproduce in that second object
    a state indistinguishable from
    the state of the first object.
    𝒪(r.size())