zar*_*rro 1 c++ random struct std deleted-functions
我正在尝试围绕标准随机数生成器编写一个简单的结构。根据编译器,我可以初始化此类,但是当我尝试使用该函数时,它会出现以下错误:
错误 C2280 'RandNormGen::RandNormGen(const RandNormGen &)':尝试引用已删除的函数
我不完全理解这意味着什么或该怎么做,但我认为我将其范围缩小到与 std ::random_device rd;有关。
这是我的结构:
struct RandNormGen {
std::random_device rd;
std::mt19937 gen;
std::normal_distribution<float> normalDist;
RandNormGen() {
gen = std::mt19937(rd());
normalDist = std::normal_distribution<float>(0, 1);
}
float randFloat(float sigma, float mean = 0) {
float r = normalDist(gen) * sigma + mean;
return r;
}
};
Run Code Online (Sandbox Code Playgroud)
任何帮助或见解将不胜感激!
std::random_device不可复制或移动。所以你的类也不能被复制或移动。
然而,保留该实例实际上没有任何意义std::random_device。您(希望)仅使用它来为实际的随机数生成器提供种子。因此,将其从结构体中删除,改为在构造函数中:
gen = std::mt19937(std::random_device{}());
Run Code Online (Sandbox Code Playgroud)
或者完全跳过构造函数并使用默认成员初始值设定项,因为默认构造函数除了初始化成员之外什么也不做:
struct RandNormGen {
std::mt19937 gen{std::random_device{}()};
std::normal_distribution<float> normalDist;
float randFloat(float sigma, float mean = 0) {
float r = normalDist(gen) * sigma + mean;
return r;
}
};
Run Code Online (Sandbox Code Playgroud)
( 的默认构造函数std::normal_distribution已经初始化为分布参数 和 ,0但1也std::normal_distribution<float> normalDist{0, 1};可以工作。)
但是,请注意您所做的事情首先会导致需要复制构造函数。
如果您实际上复制而不是移动类对象,则最终会得到该类的两个实例,它们具有相同的随机数生成器状态,这意味着副本中生成的随机数不会与原始中生成的随机数不同。
如果这不是您想要的行为,您可以显式删除复制构造函数,以便只允许移动:
RandNormGen() = default;
RandNormGen(const RandNormGen&) = delete;
RandNormGen(RandNormGen&&) = default;
RandNormGen& operator=(const RandNormGen&) = delete;
RandNormGen& operator=(RandNormGen&&) = default;
Run Code Online (Sandbox Code Playgroud)
或者您可以使用预期的语义定义复制构造函数和赋值运算符(例如重新播种生成器)。
更一般地说,考虑将随机数生成器移出类。为每个对象配备一个随机生成器通常没有任何意义。通常,程序中的每个线程都有一个生成器就足够了。
| 归档时间: |
|
| 查看次数: |
313 次 |
| 最近记录: |