这是一个算法std::shuffle
来自https://en.cppreference.com/w/cpp/algorithm/random_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)
将生成器作为左值或右值转发?为什么 using 声明位于循环体内部而不是外部?将其保留在内部(迭代)是否会影响性能?谢谢!
最佳答案
Why the algorithm takes a forwarding reference to the generator
URGB&&
g
?
因为算法不想复制generator
,它通过引用传递,并且为了能够接受临时右值 generator
,它需要一个转发引用。
As long as it didn't use
std::forward<URGB>(g)
to forward the generator either as an l-value or as an r-value?
因为generator
不仅被调用一次。如果右值被转发,它的状态可能会在下一次调用之前发生改变。
Why the using declaration is inside of loop body rather than outside of it?
这就是所谓的 std::swap
two-step ,并且惯用方式是使用不合格的 swap
紧接着 using std::swap
。把它放在循环内部的好处是它的范围仅限于循环,放在外面可能会污染命名。
Does leaving it inside (iteratively) affects performance?
没有。
关于c++ - std::shuffle 的可能实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69928319/