为什么在C ++ 14中不推荐使用std :: shuffle方法?

时间:2014-03-24 02:30:10

标签: c++ c++11 deprecated c++14 stl-algorithm

根据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

它不会显示为不同的功能减速度具有默认参数设置。这背后的原因是什么?是否添加了某种替代方案?

5 个答案:

答案 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