Как генерировать случайные числа в С++, используя элементы заголовка ‹random›?

Я научился программировать на C# и начал изучать C++. Я использую интегрированную среду разработки Visual Studio 2010. Я пытаюсь генерировать случайные числа с классами распределения, доступными в <random>. Например, я попытался сделать следующее:

    #include <random>
std::normal_distribution<double> *normal = new normal_distribution<double>(0.0, 0.0);
std::knuth_b *engine = new knuth_b();
std::variate_generator<knuth_b, normal_distribution<double>> *rnd;  
rnd = new variate_generator<knuth_b, normal_distribution<double>>(engine, normal);

Последняя строка выдает ошибку компилятора: IntelliSense: нет экземпляра конструктора "std::tr1::variate_generator‹_Engine, _Distrib>::variate_generator [с _Engine=std::tr1::knuth_b, _Distrib=std::tr1:: normal_distribution]" соответствует списку аргументов

Мои аргументы выглядят нормально, что я делаю не так? Когда здесь создается экземпляр класса variate_generator, какой метод вы вызываете, чтобы получить следующее случайное число, то есть System.Random.Next() в .NET?


person T. Webster    schedule 14.09.2010    source источник


Ответы (2)


В C++0x нет variate_generator, но std::bind работает так же хорошо. Следующее компилируется и запускается в GCC 4.5.2 и MSVC 2010 Express:

#include <random>
#include <functional>
#include <iostream>
int main()
{
    std::normal_distribution<> normal(10.0, 3.0); // mean 10, sigma 3
    std::random_device rd;
    std::mt19937 engine(rd()); // knuth_b fails in MSVC2010, but compiles in GCC
    std::function<double()> rnd = std::bind(normal, engine);

    std::cout << rnd() << '\n';
    std::cout << rnd() << '\n';
    std::cout << rnd() << '\n';
    std::cout << rnd() << '\n';
}

PS: по возможности избегайте new.

person Cubbi    schedule 14.09.2010
comment
Круто спасибо все работает и теперь я знаю про ‹функциональную› библиотеку. - person T. Webster; 14.09.2010

ПРЕДУПРЕЖДЕНИЕ. Обратите внимание, что приведенное выше решение связывает копию движка, а не ссылку на движок. Таким образом, если вы также выполните: std::function rnd2 = std::bind(normal, engine); тогда объект rnd и объект rnd2 будут генерировать одну и ту же последовательность случайных чисел.

person Mike Albert    schedule 08.03.2011
comment
Больше комментарий, чем ответ, но очень точный! - person Blindy; 22.04.2011