簡體   English   中英

將mt19937與random_device一起用作靜態類成員時出錯

[英]Error in using mt19937 with random_device as static class members

我有一個名為RandomNumberGenerator的類,我想用mt19937算法生成一個隨機數。

我正在創建一個random_device對象作為種子。

當我編譯時,我收到的錯誤是:
"No member named generate in std::__1::random_device".
我無法理解錯誤。 也許我在初始化random_devicemt19937的對象的方式上 做錯了但是我無法弄清楚出了什么問題。
感謝一些幫助..

RandomNumberGenerator.h

class RandomNumberGenerator
{
    static std::random_device   m_rd;
    static std::mt19937         m_rng;
public:
    static double getRandomNumber(const double& rangeStart, const double& rangeEnd);
};

RandomNumberGenerator.cpp

#include "RandomNumberGenerator.h"

std::random_device   RandomNumberGenerator::m_rd;
std::mt19937         RandomNumberGenerator::m_rng(RandomNumberGenerator::m_rd);

double RandomNumberGenerator::getRandomNumber(const double& rangeStart, const double& rangeEnd)
{
    std::uniform_real_distribution<> randomizer(rangeStart, rangeEnd);
    return randomizer(m_rng);
}

啊,你只錯過了一件小物品。

std::mt19937 RandomNumberGenerator::m_rng(RandomNumberGenerator::m_rd);

上面的行是發送實例而不是種子。 因此,它必須具有generate函數來提供它沒有的種子。 只需更改該行即可調用仿函數,一切都很順利。

std::mt19937 RandomNumberGenerator::m_rng(RandomNumberGenerator::m_rd());

注意:

另外需要注意的一點是,您要在每次調用時分配一個新的std::uniform_real_distribution 雖然分布對象的重量很輕,但只要rangeStartrangeEnd對后續調用保持不變,也可以考慮使其靜態化。 但是,如果您做出決定,初始化范圍值將是一個更艱難的決定。

如果您的程序在整個生命周期中都不使用此類,請考慮將其作為實例類,並在ctor上取范圍,以便在生成數字后進行完全清理。

希望這可以幫助。

編輯:

如果你肯定希望它是靜態的,另一種選擇是分配並完全清理函數中的所有對象,這些對象將填充所有需要的值,類似於以下內容:

template<typename T, typename DISTRIBUTION>
static void fill(T* buffer, uint32_t const count, T const min, T const max)
{
    ASSERT(buffer);
    ASSERT(count);
    ASSERT(max > min);

    std::random_device randomDevice;
    std::mt19937_64 twisterEngine { randomDevice() };
    DISTRIBUTION<T> distribution(min, max);
    for (uint32_t bufferLocation = 0; bufferLocation < count; ++bufferLocation)
        buffer[bufferLocation] = distribution(twisterEngine);
}

然后將其用於以下各種類型:

uint32_t const COUNT = 31u;
double realValues[COUNT];
uint32_t intValues[COUNT];

RandomNumberGenerator::fill<double, std::uniform_real_distribution<double>>(&realValues[0], COUNT, 100.0, 200.0);
RandomNumberGenerator::fill<uint32_t, std::uniform_int_distribution<uint32_t>>(intValues, COUNT, 100u, 200u);

如果這看起來像一個丑陋的界面,那么使fill私有,並提供干凈的公共方法,以提供您希望支持的幾種類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM