根据cppreference.com上的std::shufle参考网站,c ++ 14中不推荐使用以下方法:
template< class RandomIt >
void random_shuffle( RandomIt first, RandomIt last );
为什么我们不再能够在不传递第三个参数的情况下调用以下函数?
std::random_shuffle(v.begin(),v.end()); //no longer valid in c++14
它不会显示为不同的功能减速度具有默认参数设置。这背后的原因是什么?是否添加了某种替代方案?
答案 0 :(得分:44)
std::random_shuffle
可以在random
C系列函数下使用。这些函数使用种子和其他状态的全局状态。
所以它被弃用了,因为shuffle
会做同样的事情,但更好。也就是说,它使用来自C ++ 11的新<random>
标头,它不使用全局状态,但它自己的对象使用生成器,设备和分发。
答案 1 :(得分:41)
std::random_shuffle
(有效)被std::shuffle
取代。您确实需要传递第三个参数(随机数生成器),但作为交换,您可以获得更好的定义和(通常)行为。
std::random_shuffle
的定义相当差。它通常使用rand()
生成随机数,但没有说明它是否(如果是这样)如何调用srand
,所以你不能({1}}依赖rand
种子你想要的(如果你播种了,你就不能依赖于它的使用)。如果记忆服务,也有一些令人困惑(有点自相矛盾)的语言,可以解释为random_shuffle
根本不能使用rand
,和/或它不能#&# 39;用srand
种子。即使充其量,rand()
的许多实现都很差,所以即使在最好的情况下,也不能依赖有用的结果。
底线:random_shuffle
没有损失。请改用std::shuffle
,您的代码会更好。
答案 2 :(得分:15)
我们可以在本文档N3775: Deprecating rand and Friends中找到理由:
因此,我们现在建议执行该计划的下一步,以阻止使用该计划 传统的C函数rand以及相关的种子函数srand和upper limit宏 RAND_MAX。 6 特别是,我们建议通过正式弃用来开始这种转变:
- rand,srand,以及RAND_MAX和
- 算法random_shuffle()(但是保持随机播放)。
弃用random_shuffle()的基本原理是指定一个重载依赖 在rand上,指定另一个重载以便需要难以生成的分发 来自用户的对象;这种分布已经是我们保留的洗牌的隐含部分。
和后来的文件Discouraging rand() in C++14, v2重申了这一立场。
更新
正如Howard Hinnant所说,N3775
有错误:rand_shuffle()
被允许但不需要在引擎盖下使用rand()
,但这不会改变原理。
答案 3 :(得分:6)
random_shuffle
已被弃用,因为其RNG未指定 - 不仅您不必指定它,而且标准本身并未指定它。例如,在VC ++上,它使用rand()
,实现得非常差!
答案 4 :(得分:0)
其他回答回答了这个问题,但是 如果有人正在寻找一些可能适合您需要的剪切粘贴代码,以下内容可能会奏效:
#include <random>
...
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(v.begin(), v.end(), g);
rd
在许多平台上产生非确定性随机数据,生成器 g
使用具有大状态的 Mersenne Twister pseudo-random generator。