提问人:zarro 提问时间:3/26/2022 更新时间:3/26/2022 访问量:279
在结构中使用随机库后删除了函数错误
Deleted function error after using random lib in struct
问:
我正在尝试围绕 std 随机数生成器编写一个简单的结构。根据编译器,我可以初始化这个类,但是当我尝试使用该函数时,它给出了以下错误:
错误 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;
}
};
任何帮助或见解将不胜感激!
答:
std::random_device
不可复制或移动。因此,您的类也无法复制或移动。
但是,保留实例实际上没有任何意义。你(希望)只用它来播种实际的随机数生成器。因此,将其从结构中删除,而是在构造函数中:std::random_device
gen = std::mt19937(std::random_device{}());
或者完全跳过构造函数并使用默认成员初始值设定项,因为默认构造函数除了初始化成员之外什么都不做:
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;
}
};
(的默认构造函数 already 初始化为 和 but 的分布参数。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;
或者,您可以使用预期的语义定义复制构造函数和赋值运算符(例如,重新设定生成器的种子)。
更一般地说,考虑将随机数生成器移出类。通常,为每个对象设置一个随机生成器实际上没有任何意义。通常,程序中每个线程都有一个生成器就足够了。
评论
上一个:为什么无法初始化地图?
评论
RandNormGen::RandNormGen(const RandNormGen &)