调用 RandGenerator 的隐式删除复制构造函数
Call to implicitly-deleted copy constructor of RandGenerator
我有一个class创建一个对象来产生一定范围内的随机数,代码看起来像这样
#pragma once
#include <random>
class RandGenerator
{
public:
RandGenerator();
RandGenerator(const float& min, const float& max);
float nextRandom();
private:
std::random_device mRandDevice;
std::mt19937 mGenerator;
std::uniform_real_distribution<> mSampler;
};
RandGenerator::RandGenerator() : RandGenerator(0.f, 1.f)
{}
RandGenerator::RandGenerator(const float& min, const float& max)
{
mGenerator = std::mt19937(mRandDevice());
mSampler = std::uniform_real_distribution<>(min, max);
}
float RandGenerator::nextRandom()
{
return mSampler(mGenerator);
}
然后,我创建了另一个 class,它有一个 RandGenerator 实例,可以从单位球体中采样(非常简单和幼稚,但仅用于学习目的),它看起来像
#pragma once
#include "randgenerator.h"
#include "point.h"
class UnitSphereSampler
{
public:
UnitSphereSampler();
Point nextSample();
private:
RandGenerator mRandGenerator;
};
UnitSphereSampler::UnitSphereSampler() :
mRandGenerator(RandGenerator(-1.f, 1.f)) // ERROR HERE
{
}
Point UnitSphereSampler::nextSample()
{
Point p;
do
{
float x = mRandGenerator.nextRandom();
float y = mRandGenerator.nextRandom();
float z = mRandGenerator.nextRandom();
p = Point(x, y, z);
} while ((p - Point(0.f)).normSq() >= 1.f);
return p;
}
据我所知in this c++ reference 对象std::random_device
没有复制构造函数,这就是我在UnitSphereSampler class 的构造函数中使用mRandGenerator(RandGenerator(-1.f, 1.f))
的原因。
这在 VS2013 中运行良好,但是,我尝试在 OS X Sierra 中编译并得到错误
Call to implicitly-deleted copy constructor of RandGenerator
我试图指出正在复制的位置,但我似乎找不到它,我是在寻找正确的东西还是我还缺少其他东西?我认为我初始化 RandGenerator 的方式避免调用复制构造函数。有什么建议吗?
我认为这确实与在 mRandGenerator(RandGenerator(-1.f, 1.f))
行中生成的副本有关
再分析一点它会创建一个 RandGenerator
右值,我相信它会调用编译器隐式定义的移动构造函数,即 RandGenerator(const RandGenerator&& rg)
现在,即使调用了 RandGenerator 的移动构造函数,它也必须 复制 不允许的对象 std::random_device
因此给出错误。
我刚意识到这个,但不确定,我请更多有经验的人发表意见and/or完成这个答案。
与此同时,我将使用一个指向 RandGenerator 的指针,这将避免进行完美的复制和编译,即
UnitSphereSampler::UnitSphereSampler()
{
mRandGenerator = new RandGenerator(-1.f, 1.f);
}
其中 mRandGenerator
的类型为 RandGenerator*
。
我有一个class创建一个对象来产生一定范围内的随机数,代码看起来像这样
#pragma once
#include <random>
class RandGenerator
{
public:
RandGenerator();
RandGenerator(const float& min, const float& max);
float nextRandom();
private:
std::random_device mRandDevice;
std::mt19937 mGenerator;
std::uniform_real_distribution<> mSampler;
};
RandGenerator::RandGenerator() : RandGenerator(0.f, 1.f)
{}
RandGenerator::RandGenerator(const float& min, const float& max)
{
mGenerator = std::mt19937(mRandDevice());
mSampler = std::uniform_real_distribution<>(min, max);
}
float RandGenerator::nextRandom()
{
return mSampler(mGenerator);
}
然后,我创建了另一个 class,它有一个 RandGenerator 实例,可以从单位球体中采样(非常简单和幼稚,但仅用于学习目的),它看起来像
#pragma once
#include "randgenerator.h"
#include "point.h"
class UnitSphereSampler
{
public:
UnitSphereSampler();
Point nextSample();
private:
RandGenerator mRandGenerator;
};
UnitSphereSampler::UnitSphereSampler() :
mRandGenerator(RandGenerator(-1.f, 1.f)) // ERROR HERE
{
}
Point UnitSphereSampler::nextSample()
{
Point p;
do
{
float x = mRandGenerator.nextRandom();
float y = mRandGenerator.nextRandom();
float z = mRandGenerator.nextRandom();
p = Point(x, y, z);
} while ((p - Point(0.f)).normSq() >= 1.f);
return p;
}
据我所知in this c++ reference 对象std::random_device
没有复制构造函数,这就是我在UnitSphereSampler class 的构造函数中使用mRandGenerator(RandGenerator(-1.f, 1.f))
的原因。
这在 VS2013 中运行良好,但是,我尝试在 OS X Sierra 中编译并得到错误
Call to implicitly-deleted copy constructor of RandGenerator
我试图指出正在复制的位置,但我似乎找不到它,我是在寻找正确的东西还是我还缺少其他东西?我认为我初始化 RandGenerator 的方式避免调用复制构造函数。有什么建议吗?
我认为这确实与在 mRandGenerator(RandGenerator(-1.f, 1.f))
再分析一点它会创建一个 RandGenerator
右值,我相信它会调用编译器隐式定义的移动构造函数,即 RandGenerator(const RandGenerator&& rg)
现在,即使调用了 RandGenerator 的移动构造函数,它也必须 复制 不允许的对象 std::random_device
因此给出错误。
我刚意识到这个,但不确定,我请更多有经验的人发表意见and/or完成这个答案。
与此同时,我将使用一个指向 RandGenerator 的指针,这将避免进行完美的复制和编译,即
UnitSphereSampler::UnitSphereSampler()
{
mRandGenerator = new RandGenerator(-1.f, 1.f);
}
其中 mRandGenerator
的类型为 RandGenerator*
。