为什么 `std::sample` 将 `UniformRandomBitGenerator` 作为 &&?
Why does `std::sample` take `UniformRandomBitGenerator` as &&?
std::uniform_real_distribution::operator()
是:
template< class Generator >
result_type operator()( Generator& g );
而 std::sample
是:
template< class PopulationIterator, class SampleIterator,
class Distance, class UniformRandomBitGenerator >
SampleIterator sample( PopulationIterator first, PopulationIterator last,
SampleIterator out, Distance n,
UniformRandomBitGenerator&& g);
我在这里只引用 uniform_real_distribution
,因为它是标准中另一个采用生成器的地方,sample
和 std::uniform_real_distribution::operator()
以不同的方式采用它们。只是好奇这背后的原理。
sample
最终还是需要一个non-const generator,但是允许传入临时generator也很方便,如果是用non-const拿generator就不行了-const 左值引用。显而易见的解决方案:转发引用,如果提供了 const 左值,则不可避免的编译器错误。
另一方面,我认为将临时生成器传递给单个分发调用几乎不会像往常一样——事实上,考虑到 constructing/initializing 大多数生成器的费用,绝大多数时间这样做将是一个效率低下的坑。有鉴于此,例如std::vector
缺少 push_front
和 pop_front
,通过积极使其成为反模式来阻止这种低效率可能是最好的做法。
按时间顺序,<random>
明显早于 C++11(它来自 TR1,以及之前的 Boost),并且在合并到标准.
std::uniform_real_distribution::operator()
是:
template< class Generator >
result_type operator()( Generator& g );
而 std::sample
是:
template< class PopulationIterator, class SampleIterator,
class Distance, class UniformRandomBitGenerator >
SampleIterator sample( PopulationIterator first, PopulationIterator last,
SampleIterator out, Distance n,
UniformRandomBitGenerator&& g);
我在这里只引用 uniform_real_distribution
,因为它是标准中另一个采用生成器的地方,sample
和 std::uniform_real_distribution::operator()
以不同的方式采用它们。只是好奇这背后的原理。
sample
最终还是需要一个non-const generator,但是允许传入临时generator也很方便,如果是用non-const拿generator就不行了-const 左值引用。显而易见的解决方案:转发引用,如果提供了 const 左值,则不可避免的编译器错误。另一方面,我认为将临时生成器传递给单个分发调用几乎不会像往常一样——事实上,考虑到 constructing/initializing 大多数生成器的费用,绝大多数时间这样做将是一个效率低下的坑。有鉴于此,例如
std::vector
缺少push_front
和pop_front
,通过积极使其成为反模式来阻止这种低效率可能是最好的做法。按时间顺序,
<random>
明显早于 C++11(它来自 TR1,以及之前的 Boost),并且在合并到标准.