我有以下類繼承結構
#include <random>
class ABC{
protected:
std::mt19937_64 rng;
double a();//calls random correction
virtual double random_correction() const=0;
public:
double x;
explicit ABC(const double x0) :
rng(std::random_device{}()), x(x0){}
ABC(const ABC& other)=default;
ABC& operator=(const ABC& other)=default;
ABC(ABC&& other) noexcept = default;
ABC& operator=(ABC&& other) noexcept = default ;
virtual ~ABC()=default;
virtual void update(const int step_number)=0;//calls a and uses rng
};
class D1 : public ABC{
private:
double y;
double random_correction() const override {return 0;};
public:
D1(const double x0, const double y0):
ABC(x0), y(y0){}
D1(const D1& other)=default;
D1& operator=(const D1& other)=default;
D1(D1&& other) noexcept = default;
D1& operator=(D1&& other) noexcept = default ;
~D1() override=default;
void update(const int step_number) override;
};
class D2 : public D1{
private:
double noise;
double random_correction() const override {
static std::uniform_real_distribution<> u{-noise, noise};
return u(rng); //error here
};
public:
D2(const double x0, const double y0, const double na):
D1(x0,y0), noise(na) {}
D2(const D2& other)=default;
D2& operator=(const D2& other)=default;
D2(D2&& other) noexcept = default;
D2& operator=(D2&& other) noexcept = default ;
~D2() override=default;
};
在 D2 的 random_correction 的定義中,我得到以下錯誤:“在函式模板專業化的實體化中 'std::uniform_real_distribution::operator()<const std::mersenne_twister_engine<unsigned long, 64, 312, 156, 31, 13043109905998158313, 29、6148914691236517205、17、8202884508482404352、37、18444473444759240704、43、6364136223846793005> >'在這里請求“。如果我洗掉所有宣告中的 const 限定符,錯誤就會消失。為什么?成員函式中的 const 限定符不是意味著不會修改類的任何成員嗎?
作為一種解決方法,我認為我可以以這種方式修改 D2 類
class D2 : public D1{
private:
double noise;
std::uniform_real_distribution<> u;
double random_correction() const override {
return u(rng); //error always here
};
public:
D2(const double x0, const double y0, const double na):
D1(x0,y0), noise(na) {u.param(std::uniform_real_distribution<>::param_type{-noise, noise});}
D2(const D2& other)=default;
D2& operator=(const D2& other)=default;
D2(D2&& other) noexcept = default;
D2& operator=(D2&& other) noexcept = default ;
~D2() override=default;
};
However now I get the error: "no matching function for call to object of type 'const std::uniform_real_distribution<>'". I suppose because generating a random number changes the state of u (and maybe of rng as well). Is this correct? Is it convenient to have a distribution as a member?
P.S. Please, if there is any design error or inefficiency point it out to me.
uj5u.com熱心網友回復:
生成亂數不會改變u. 它的狀態就是要生成的值的范圍。
但它確實改變了rng. 偽亂數生成器通常具有確定性含義,rng()由當前狀態確定,并且狀態將在評估時發生變化,因此下次將產生不同的值。
要解決編譯問題,您可以洗掉函式的 const 宣告,也可以宣告rng為mutable. 它仍然會承受某些問題,例如“同時訪問類實體會導致資料競爭”。所以你可能會考慮重新考慮設計。
RNG 引擎可以從thread_local關鍵字中受益……但您需要以某種方式對其進行設計,以免導致可能有點棘手的性能問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/441485.html
標籤:c inheritance random
上一篇:使用DllImport從c#呼叫時出現std::wstring問題
下一篇:多載和鏈表
