使用<random>在C++中的随机数顺序

Adr*_*one 39 c++ random operator-precedence c++11

我有以下代码,我写的是为了测试更大程序的一部分:

#include <fstream>
#include <random>
#include <iostream>
using namespace std ;

int main()
{
  mt19937_64 Generator(12187) ;
  mt19937_64 Generator2(12187) ;
  uniform_int_distribution<int> D1(1,6) ;

  cout << D1(Generator) << " " ;
  cout << D1(Generator) << " " << D1(Generator) << endl ;
  cout << D1(Generator2) << " " << D1(Generator2) << " " << D1(Generator2) << endl ;

  ofstream g1("g1.dat") ;
  g1 << Generator ;
  g1.close() ;
  ofstream g2("g2.dat") ;
  g2 << Generator2 ;
  g2.close() ;
}                                                            
Run Code Online (Sandbox Code Playgroud)

这两个生成器的种子具有相同的值,因此我预计输出中的第二行与第一行相同.相反,输出是

1 1 3
1 3 1
Run Code Online (Sandbox Code Playgroud)

*.dat文件中打印的两个生成器的状态是相同的.我想知道在随机数生成中是否可能存在一些隐藏的多线程导致顺序不匹配.

我用g++Linux上的5.3.0版本编译了旗帜-std=c++11.

在此先感谢您的帮助.

Ric*_*ges 42

x << y是一个函数调用的语法糖operator<<(x, y).

您将记住,c ++标准对函数调用的参数的评估顺序没有限制.

因此编译器可以自由地发出首先计算x或y的代码.

从标准:§5注2:

操作符可以重载,也就是说,当应用于类类型(第9节)或枚举类型(7.2)的表达式时赋予操作符.重载运算符的使用将转换为函数调用,如13.5中所述.重载运算符遵循第5章中指定的语法规则,但操作数类型,值类别和评估顺序的要求将替换为函数调用的规则.

  • @alain:`<<(c,d)`必须在任何其他`<<`之前进行评估,但是a,b,c,d可以按任何顺序进行评估(并保存结果). (12认同)
  • 我不确定你说的是否适用于此,是不是更像是<<(a,(b,<<(c,d)))` 这样"<<(c,d)`必须首先评估? (5认同)

ala*_*ain 36

那是因为这条线的评价顺序

cout << D1(Generator2) << " " << D1(Generator2) << " " << D1(Generator2) << endl ;
Run Code Online (Sandbox Code Playgroud)

不是你的想法.

你可以用这个来测试它:

int f() {
  static int i = 0;
  return i++;
}

int main() {
  cout << f() << " " << f() << " " << f() << endl ;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出: 2 1 0


订单未由C++标准指定,因此其他编译器的订单可能不同,请参阅Richard Hodges的回答.

  • @alain,No.`cout << f()<< g();`是`operator <<(operator <<(cout,f()),g())`.很明显,第一次调用<<必须在第二次调用之前发生(因为第一次调用的结果是第二次调用).在调用`f`和`g`之间没有*排序*.在任何对"<<"的调用之前,编译器完全可以自己调用它们. (5认同)
  • @AviGinsburg:请注意,当alain说"输出'2 1 0`"时,这次是他用他的编译器在他的机器上获得的输出.允许六种可能的排序中的任何一种(尽管大多数系统将产生"2 1 0"或"0 1 2"). (4认同)

Ane*_*dar 5

程序稍有变化就会发现会发生什么:

#include <fstream>
#include <random>
#include <iostream>
using namespace std ;

int main()
{
  mt19937_64 Generator(12187) ;
  mt19937_64 Generator2(12187) ;
  uniform_int_distribution<int> D1(1,100) ;

  cout << D1(Generator) << " " ;
  cout << D1(Generator) << " " ;
  cout << D1(Generator) << endl ;
  cout << D1(Generator2) << " " << D1(Generator2) << " " << D1(Generator2) << endl ;
}
Run Code Online (Sandbox Code Playgroud)

输出:

4 48 12
12 48 4
Run Code Online (Sandbox Code Playgroud)

所以你的生成器会产生相同的结果 - 但你的cout-line参数的顺序是按不同的顺序计算的.

在线试用:http: //ideone.com/rsoqDe

  • 这如何展示与OPs代码不同/更多的东西? (2认同)