在std::uniform_real_distribution的文档中,初始化均匀实数随机数生成器的表示法是使用圆括号:
std::uniform_real_distribution rand01(0,1)
但是,当我将其定义为类变量的成员时
#include <iostream>
#include <random>
class randomnumber
{
public:
randomnumber()
{
std::random_device rd;
generator.seed(rd());
};
double get_rn()
{
return rand01(generator);
}
private :
std::mt19937 generator;
std::uniform_real_distribution<double> rand01(0.,1.);
};
int main(int argc,char *argv[])
{
randomnumber randnum;
for(int i=0;i<100;i++)
std::cout << randnum.get_rn() << std::endl;
}
编译器失败并出现错误:
randtest.cpp:20:53: error: expected identifier before numeric constant
20 | std::uniform_real_distribution<double> rand01(0.,1.);
| ^~
randtest.cpp:20:53: error: expected ‘,’ or ‘...’ before numeric constant
randtest.cpp: In member function ‘double randomnumber::get_rn()’:
randtest.cpp:15:24: error: cannot convert ‘std::mt19937’ {aka ‘std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>’} to ‘int’
15 | return rand01(generator);
| ^~~~~~~~~
| |
| std::mt19937 {aka std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>}
randtest.cpp:20:53: note: initializing argument 1 of ‘std::uniform_real_distribution<double> randomnumber::rand01(int)’
20 | std::uniform_real_distribution<double> rand01(0.,1.);
解决方法是使用大括号
{}
而不是圆括号 ()
。
问题是,这个修复是根本修复吗?意思是,我可以相信带有
{}
的固定代码总是生成 0 到 1 之间的统一随机数吗?
另外,为了将来类似情况的目的,如果有人能向我解释为什么编译器会以这种方式运行,那就太好了。
我用于编译
g++
g++ -std=c++11 randtest.cpp
:
g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
此修复是根本修复吗?
对于这段代码,是的。 但一般情况下不是这样。
我可以相信带有 {} 的固定代码总是生成 0 到 1 之间的统一随机数吗?
是的,
std::uniform_real_distribution<double> rand01{0.,1.};
通过调用与 0
为非类作用域执行的完全相同的构造函数,定义了参数为 1
和 std::uniform_real_distribution rand01(0,1)
的均匀分布。
但是当使用大括号时,编译器搜索构造函数的方式是不同的。 特别是对于打算作为集合工作的类(例如
std::vector
),大括号可以选择不同的构造函数。 这种情况发生的一个强烈迹象是,当类有一个(或多个)某些 std::initializer_list<...>
的构造函数时