c++ - std::shuffle 的可能实现
问题描述
这是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 声明在循环体内部而不是在循环体外部?将其留在内部(迭代地)会影响性能吗?谢谢!
解决方案
为什么算法需要对生成器的转发引用
URGB&&
g
?
因为算法不想复制generator
,它通过引用传递,并且为了能够接受临时右值generator
,它需要一个转发引用。
只要它不用于
std::forward<URGB>(g)
将生成器作为左值或右值转发?
因为generator
不仅仅被调用一次。如果右值被转发,它的状态可能会在下一次调用之前改变。
为什么 using 声明在循环体内部而不是在循环体外部?
这就是所谓std::swap
的两步,swap
在 之后立即使用 unqualified 是惯用的using std::swap
。放在循环里面的好处是它的作用域仅限于循环,放在外面可能会污染命名。
将其留在内部(迭代地)会影响性能吗?
不。
推荐阅读
- html - 如何使用 Bootstrap 4 使我的布局响应
- c# - 为什么 Ajax 的 JSON 对象会抛出错误,而 json 文件不会?
- c# - 从 c# 更新图层 Autocad Map 2014
- sql - 如何将 unix 时间戳转换为带有时区的日期?
- javascript - 如何将 ajax url 参数中的变量传递给 laravel 路由?
- java - java惰性流构造中的问题
- salesforce-commerce-cloud - SalesForce 商务云。截取用户和订单数据
- postgresql - 表达式索引的奇怪行为
- kotlin - 如何在kotlin中将小时转换为分钟并正确传递给viewholder?
- plsql - 一天的程序运行细节