782. Extended seed_seq constructor is useless

Section: 29.5.8.1 [rand.util.seedseq] Status: CD1 Submitter: Daniel Krügler Opened: 2008-01-27 Last modified: 2015-10-20

Priority: Not Prioritized

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

View all issues with CD1 status.

Discussion:

Part of the resolution of n2423, issue 8 was the proposal to extend the seed_seq constructor accepting an input range as follows (which is now part of N2461):

template<class InputIterator,
size_t u = numeric_limits<iterator_traits<InputIterator>::value_type>::digits>
seed_seq(InputIterator begin, InputIterator end);

First, the expression iterator_traits<InputIterator>::value_type is invalid due to missing typename keyword, which is easy to fix.

Second (and worse), while the language now supports default template arguments of function templates, this customization point via the second size_t template parameter is of no advantage, because u can never be deduced, and worse - because it is a constructor function template - it can also never be explicitly provided (13.10.2 [temp.arg.explicit]/7).

The question arises, which advantages result from a compile-time knowledge of u versus a run time knowledge? If run time knowledge suffices, this parameter should be provided as normal function default argument [Resolution marked (A)], if compile-time knowledge is important, this could be done via a tagging template or more user-friendly via a standardized helper generator function (make_seed_seq), which allows this [Resolution marked (B)].

[ Bellevue: ]

Fermilab does not have a strong opinion. Would prefer to go with solution A. Bill agrees that solution A is a lot simpler and does the job.

Proposed Resolution: Accept Solution A.

Issue 803 claims to make this issue moot.

Proposed resolution:

  1. In 29.5.8.1 [rand.util.seedseq]/2, class seed_seq synopsis replace:

    class seed_seq 
    { 
    public:
       ...
       template<class InputIterator,
          size_t u = numeric_limits<iterator_traits<InputIterator>::value_type>::digits>
              seed_seq(InputIterator begin, InputIterator end,
              size_t u = numeric_limits<typename iterator_traits<InputIterator>::value_type>::digits);
       ...
    };
    

    and do a similar replacement in the member description between p.3 and p.4.

  2. In 29.5.8.1 [rand.util.seedseq]/2, class seed_seq synopsis and in the member description between p.3 and p.4 replace:

    template<class InputIterator,
      size_t u = numeric_limits<iterator_traits<InputIterator>::value_type>::digits>
          seed_seq(InputIterator begin, InputIterator end);
    template<class InputIterator, size_t u>
    seed_seq(InputIterator begin, InputIterator end, implementation-defined s);
    

    In 29.5.2 [rand.synopsis], header <random> synopsis, immediately after the class seed_seq declaration and in 29.5.8.1 [rand.util.seedseq]/2, immediately after the class seed_seq definition add:

    template<size_t u, class InputIterator>
      seed_seq make_seed_seq(InputIterator begin, InputIterator end);
    

    In 29.5.8.1 [rand.util.seedseq], just before p.5 insert two paragraphs:

    The first constructor behaves as if it would provide an integral constant expression u of type size_t of value numeric_limits<typename iterator_traits<InputIterator>::value_type>::digits.

    The second constructor uses an implementation-defined mechanism to provide an integral constant expression u of type size_t and is called by the function make_seed_seq.

    In 29.5.8.1 [rand.util.seedseq], just after the last paragraph add:

    template<size_t u, class InputIterator>
       seed_seq make_seed_seq(InputIterator begin, InputIterator end);
    

    where u is used to construct an object s of implementation-defined type.

    Returns: seed_seq(begin, end, s);