C++ random_shuffle总是给出相同的结果

Ana*_*ria 1 c++ c++11

以下对随机shuffle的调用始终为向量v提供相同的结果

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>

using namespace std;

int main(){
  vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  srand(time(0));
  random_shuffle(v.begin(), v.end());
  for (int i = 0; i < v.size(); ++i) printf("%d ", v[i]); printf("\n");
  printf("%d\n", rand() % 100);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我试过编译使用

g++ -std=c++0x
g++ -std=c++11
Run Code Online (Sandbox Code Playgroud)

但是每次都给出相同的结果,所以我真的不明白发生了什么.

$./a.out
7 1 4 6 8 9 5 2 3 10 
26
$ ./a.out
7 1 4 6 8 9 5 2 3 10 
41
$ ./a.out
7 1 4 6 8 9 5 2 3 10 
39
Run Code Online (Sandbox Code Playgroud)

T.C*_*.C. 5

OP的评论清楚地表明这是他们正在使用的Clang和libc ++,而不是GCC/libstdc ++.

快速浏览一下libc ++的random_shuffle实现,可以看出它使用了一个类型的对象__rs_default作为随机源,并检查__rs_default show 的实现,它只是使用了一个默认构造的std::mt19937对象:

__rs_default::result_type
__rs_default::operator()()
{
    static mt19937 __rs_g;
    return __rs_g();
}
Run Code Online (Sandbox Code Playgroud)

换句话说,在这个实现srand中对双参数版本使用的"随机性"的来源没有任何影响random_shuffle.(可怕的引用,因为它总是使用固定的种子.)请注意,random_shuffle根本不需要使用rand,所以srand无论如何你不能指望在可移植代码中"工作".

使用std::shuffle<random>设施而不是.