为什么std :: shuffle方法在C ++ 14中被弃用?

根据std :: shufle上的cppreference.com参考站点,以下方法在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 

它看起来不像一个不同的function减速有一个默认的参数设置。 这背后的原因是什么? 有没有添加一些替代品?

std::random_shuffle 可以使用C函数的random函数。 这些function使用全球状态为种子和其他状态。

所以它被淘汰,因为shuffle会做同样的,但更好。 也就是说,它使用来自C ++ 11的新的<random>标题,它不使用全局状态,而是使用发生器,设备和发行版本身的对象。

std::random_shuffle被(有效)replace为std::shuffle 。 你需要传递第三个参数(一个随机数生成器),但是作为交换,你会得到更好的定义和(通常)行为。

std::random_shuffle相当不好定义。 它通常使用rand()生成随机数,但没有说是否(以及如何如此)它称为srand ,所以你不能依赖(例如)在rand种子如何你想(如果你种植它,你不能依赖于被使用)。 如果记忆random_shuffle话,还有一些令人困惑的(有些自相矛盾的)语言,可以解释为random_shuffle根本不能使用rand和/或不能用srand来播种。 即使在最好的情况下, rand()很多实现都很差,所以即使在最好的情况下也不能依赖有用的结果。

底线: random_shuffle是没有损失。 改用std::shuffle ,你的代码会更好。

我们可以在这个文档中find理由N3775:弃用兰德和朋友说:

因此,我们现在build议执行这个计划的下一个步骤来阻止使用传统的C函数rand以及相关的种子函数srand和上限macrosRAND_MAX。 6我们特别build议通过正式废弃来开始这一转变:

  • rand,srand和RAND_MAX和
  • algorithmrandom_shuffle()(保持随机播放,但是)。

取消random_shuffle()的基本原理是指定一个重载以取决于rand,而另一个重载指定为需要来自用户的难以产生的分发对象; 这样的分配已经是我们保留的一个隐含的洗牌部分。

和后面的文档Discouraging rand()在C ++ 14中,v2重申了这个位置。

更新

正如霍华德N3775指出N3775有一个错误:允许rand_shuffle() ,但不要求在引擎盖下使用rand() ,但这不会改变的理由。

random_shuffle已经被弃用,因为它的RNG是未指定的 – 不仅仅是不必指定它,而是标准本身没有指定它。 例如在VC ++上,它使用的是rand() ,实现起来效果很差!