这是从 https://en.cppreference.com/w/cpp/algorithm/random_shufflestd::shuffle
的算法:
template<class RandomIt, class URBG> void shuffle(RandomIt first, RandomIt last, URBG&& g) { typedef typename std::iterator_traits<RandomIt>::difference_type diff_t; typedef std::uniform_int_distribution<diff_t> distr_t; typedef typename distr_t::param_type param_t; distr_t D; diff_t n = last - first; for (diff_t i = n-1; i > 0; --i) { using std::swap; swap(first[i], first[D(g, param_t(0, i))]); } }
-
为什么算法需要转发引用生成器
URGB&& g
?只要它不使用std::forward<URGB>(g)
将生成器作为 l 值或 r 值转发? -
为什么 using 声明在循环体内部而不是外部?将其留在内部(迭代)会影响性能吗?谢谢!
为什么算法需要对生成器的转发引用
URGB&&
g
?
因为算法不想复制generator
,所以它通过引用传递,并且为了能够接受临时右值generator
,它需要一个转发引用。
只要它不使用
std::forward<URGB>(g)
转发 生成器是作为 L 值还是作为 R 值?
因为generator
不仅被调用一次。如果转发右值,则在下一次调用之前可能会更改其状态。
为什么 using 声明在循环体内部而不是外部 的?
这就是所谓的std::swap
两步走,在using std::swap
之后立即使用不合格的swap
是惯用的。把它放在循环内的好处是它的范围仅限于循环,把它放在外面可能会污染命名。
将其留在内部(迭代)会影响性能吗?
不。