代码之家  ›  专栏  ›  技术社区  ›  Tom

使用paranthesis初始化std::random_uniform_real_分布

  •  1
  • Tom  · 技术社区  · 1 年前

    在the documentation 属于 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.
    
    1 回复  |  直到 1 年前
        1
  •  2
  •   Ben Voigt    1 年前

    这个修复是根本性的修复吗?

    对于这段代码,是的。但总体而言并非如此。

    我可以相信带有{}的固定代码总是生成0到1之间的统一随机数吗?

    对, std::uniform_real_distribution<double> rand01{0.,1.}; 定义了一个参数为的均匀分布 0 1 ,通过调用完全相同的构造函数 std::uniform_real_distribution rand01(0,1) 适用于非类作用域。

    但是当使用大括号时,编译器搜索构造函数的方式是不同的。特别是对于旨在作为集合工作的类(例如。 std::vector ),括号可以选择不同的构造函数。这种情况发生的一个强烈迹象是,当类为某些对象具有构造函数(或多个构造函数)时 std::initializer_list<...> .

    std::uniform_real_distribution::uniform_real_distribution() doesn't have special handling for initializer lists 这就是使您的具体示例安全的原因。

    推荐文章