David David - 8 months ago 38
C++ Question

Why does `std::sample` take `UniformRandomBitGenerator` as &&?


template< class Generator >
result_type operator()( Generator& g );


template< class PopulationIterator, class SampleIterator,
class Distance, class UniformRandomBitGenerator >
SampleIterator sample( PopulationIterator first, PopulationIterator last,
SampleIterator out, Distance n,
UniformRandomBitGenerator&& g);

I'm only referencing
here because it's another place in the standard which takes a generator, and
take them in different ways. Just curious about the rationale behind this.

  1. sample ultimately needs a non-const generator, but it's also very convenient to allow temporary generators to be passed in, which wouldn't be possible if it took the generator by non-const lvalue-reference. The obvious solution: a forwarding reference, and an inevitable compiler error if a const lvalue is supplied.

    On the other hand, I suppose it would not be nearly as usual to pass a temporary generator to a single distribution invocation – indeed, given the expense of constructing/initializing most generators, the vast majority of the time doing so would be a pit of inefficiency. In this light, as with e.g. std::vector's lack of push_front and pop_front, discouraging this inefficiency by actively making it an anti-pattern is probably the best thing to do.

  2. Chronologically, <random> predates C++11 significantly (it comes from TR1, and Boost before that), and was not necessarily thoroughly updated to exploit all new language features when incorporated into the standard.