インスタンスをインスタンス化しないクラスで作業しています。それは保護されたコンストラクタを持ち、すべてのメソッドは静的です。このクラスでは、さまざまなランダムなエンジンへの呼び出しを簡素化しています。<random>
私は、異なる配信タイプに対して同じことをする同様のクラスを持っています。私のエンジンへの静的な呼び出しはすべて、うまく動作し、複数の方法でそれらをシードすることができます。私は現在、さまざまなディストリビューションを扱うためにコンパニオンクラスに取り掛かる過程にあります。これまで私はstd::uniform_int
、std::uniform_int_distribution
、std::uniform_real
、std::uniform_real_distribution
を成功させています。今私はstd::generate_canonical
で作業を始めました。私はコンパイラエラーを開始しています。それは私がクラスインターフェイス内のテンプレート化された静的メソッドでstd :: generator_canonicalを操作する
template<class RealType = double, std::size_t numBits, class Generator>
static std::generate_canonical<RealType, numBits>& getGenerateCanonical(Generator& engine) {
static std::generate_canonical<RealType, numBits> dist(engine);
return dist;
} // getGeneratorCanonical
に取り組んでいます。この関数であり、私は構文は、このウェブサイトを形成し、次のしてきた
#ifndef RANDOM_GENERATOR_H
#define RANDOM_GENERATOR_H
#include <chrono>
#include <random>
class RandomEngine {
public:
using Clock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
std::chrono::high_resolution_clock,
std::chrono::steady_clock>;
// Used To Determine Which Seeding Process To Use
enum SeedType {
USE_CHRONO_CLOCK,
USE_RANDOM_DEVICE,
USE_SEED_VALUE,
USE_SEED_SEQ,
}; // SeedType
// This Enum Is Not In Use - It Is A Visual Reference Only; But If User Wants To
// Use It For Their Own Pupose They Are Free To Do So.
enum EngineType {
// Default Random Engine
DEFAULT_RANDOM_ENGINE,
// Linear Congruential Engines
MINSTD_RAND0,
MINSTD_RAND,
// Mersenne Twister Engines
MT19937,
MT19937_64,
// Subtract With Carry Engines
RANLUX24_BASE,
RANLUX48_BASE,
// Discard Block Engines
RANLUX24,
RANLUX48,
// Shuffle Order Engines
KNUTH_B,
}; // EngineType
protected:
RandomEngine(){}
public:
static unsigned int getTimeNow() {
unsigned int now = static_cast<unsigned int>(Clock::now().time_since_epoch().count());
return now;
} // getTimeNow
static std::random_device& getRandomDevice() {
static std::random_device device{};
return device;
} // getRandomDevice
static std::default_random_engine& getDefaultRandom(SeedType type, unsigned seedValue = 0, std::seed_seq& seq = std::seed_seq{}) {
static std::default_random_engine engine{};
if (type == USE_RANDOM_DEVICE) {
engine.seed(getRandomDevice()());
}
if (type == USE_CHRONO_CLOCK) {
engine.seed(getTimeNow());
}
if (type == USE_SEED_VALUE) {
engine.seed(seedValue);
}
if (type == USE_SEED_SEQ) {
engine.seed(seq);
}
return engine;
} // getDefaultEngine
static std::minstd_rand0& getMinStd_Rand0(SeedType type, unsigned seedValue = 0) {
static std::minstd_rand0 engine{};
if (type == USE_RANDOM_DEVICE) {
engine.seed(getRandomDevice()());
}
if (type == USE_CHRONO_CLOCK) {
engine.seed(getTimeNow());
}
if (type == USE_SEED_VALUE) {
engine.seed(seedValue);
}
return engine;
} // getMinStd_Rand0
static std::minstd_rand& getMinStd_Rand(SeedType type, unsigned seedValue = 0) {
static std::minstd_rand engine{};
if (type == USE_RANDOM_DEVICE) {
engine.seed(getRandomDevice()());
}
if (type == USE_CHRONO_CLOCK) {
engine.seed(getTimeNow());
}
if (type == USE_SEED_VALUE) {
engine.seed(seedValue);
}
return engine;
} // getMinStd_Rand
static std::mt19937& getMt19937(SeedType type, unsigned seedValue = 0) {
static std::mt19937 engine{};
if (type == USE_RANDOM_DEVICE) {
engine.seed(getRandomDevice()());
}
if (type == USE_CHRONO_CLOCK) {
engine.seed(getTimeNow());
}
if (type == USE_SEED_VALUE) {
engine.seed(seedValue);
}
return engine;
} //getMt19937
static std::mt19937_64& getMt19937_64(SeedType type, unsigned seedValue = 0) {
static std::mt19937_64 engine{};
if (type == USE_RANDOM_DEVICE) {
engine.seed(getRandomDevice()());
}
if (type == USE_CHRONO_CLOCK) {
engine.seed(getTimeNow());
}
if (type == USE_SEED_VALUE) {
engine.seed(seedValue);
}
return engine;
} // getMt19937_64
static std::ranlux24_base& getRanLux24_base(SeedType type, unsigned seedValue = 0) {
static std::ranlux24_base engine{};
if (type == USE_RANDOM_DEVICE) {
engine.seed(getRandomDevice()());
}
if (type == USE_CHRONO_CLOCK) {
engine.seed(getTimeNow());
}
if (type == USE_SEED_VALUE) {
engine.seed(seedValue);
}
return engine;
} // getRanLux24_base
static std::ranlux48_base& getRanLux48_base(SeedType type, unsigned seedValue = 0) {
static std::ranlux48_base engine{};
if (type == USE_RANDOM_DEVICE) {
engine.seed(getRandomDevice()());
}
if (type == USE_CHRONO_CLOCK) {
engine.seed(getTimeNow());
}
if (type == USE_SEED_VALUE) {
engine.seed(seedValue);
}
return engine;
} // getRanLux48_base
static std::ranlux24& getRanLux24(SeedType type, unsigned seedValue = 0) {
static std::ranlux24 engine{};
if (type == USE_RANDOM_DEVICE) {
engine.seed(getRandomDevice()());
}
if (type == USE_CHRONO_CLOCK) {
engine.seed(getTimeNow());
}
if (type == USE_SEED_VALUE) {
engine.seed(seedValue);
}
return engine;
} // getRanLux24
static std::ranlux48& getRanLux48(SeedType type, unsigned seedValue = 0) {
static std::ranlux48 engine{};
if (type == USE_RANDOM_DEVICE) {
engine.seed(getRandomDevice()());
}
if (type == USE_CHRONO_CLOCK) {
engine.seed(getTimeNow());
}
if (type == USE_SEED_VALUE) {
engine.seed(seedValue);
}
return engine;
} //getRanLux48
}; // RandomEngine
class RandomDistribution {
public:
// This Enum Is Not In Use - It Is A Visual Reference Only; But If User Wants To
// Use It For Their Own Pupose They Are Free To Do So.
enum DistributionType {
// Uniform Distributions
UNIFORM_INT,
UNIFORM_INT_DISTRIBUTION,
UNIFORM_REAL,
UNIFORM_REAL_DISTRIBUTION,
GENERATE_CANONICAL,
// Bernoulli Distributions
BERNOULLI_DISTRIBUTION,
BINOMAIL_DISTRIBUTION,
NEGATIVE_BINOMIAL_DISTRIBUTION,
GEOMETRIC_DISTRIBUTION,
// Poisson Distributions
POISSON_DISTRIBUTION,
EXPONENTIAL_DISTRIBUTION,
GAMMA_DISTRIBUTION,
WEIBULL_DISTRIBUTION,
EXTREME_VALUE_DISTRIBUTION,
// Normal Distributions
NORMAL_DISTRIBUTION,
LOGNORMAL_DISTRIBUTION,
CHI_SQUARED_DISTRIBUTION,
CAUCHY_DISTRIBUTION,
FISHER_F_DISTRIBUTION,
STUDENT_T_DISTRIBUTION,
// Sampling Distributions
DISCRETE_DISTRIBUTION,
PIECEWISE_CONSTANT_DISTRIBUTION,
PIECEWISE_LINEAR_DISTRIBUTION
}; // DistributionType
protected:
RandomDistribution(){}
public:
template<class IntType = int>
static std::uniform_int<IntType>& getUniformInt(IntType lowerBound, IntType upperBound) {
static std::uniform_int<IntType> dist(lowerBound, upperBound);
return dist;
} // getUniformInt
template<class IntType = int>
static std::uniform_int<IntType>& getUniformIntDistribution(IntType lowerBound, IntType upperBound) {
static std::uniform_int_distribution<IntType> dist(lowerBound, upperBound);
return dist;
} // getUniformIntDistribution
template<class RealType = double>
static std::uniform_real<RealType>& getUniformReal(RealType lowerBound, RealType upperBound) {
static std::uniform_real<RealType> dist(lowerBound, uppperBound);
return dist;
} // getUniformReal
template<class RealType = double>
static std::uniform_real_distribution<RealType>& getUniformRealDistribution(RealType lowerBound, RealType upperBound) {
static std::uniform_real_distribution<RealType> dist(lowerBound, upperBound);
return dist;
} // getUniformRealDistribution
template<class RealType = double, std::size_t numBits, class Generator>
static std::generate_canonical<RealType, numBits>& getGenerateCanonical(Generator& engine) {
static std::generate_canonical<RealType, numBits> dist(engine);
return dist;
} // getGeneratorCanonical
}; // RandomDistribution
typedef RandomEngine RE;
typedef RandomDistribution RD;
// #include "RandomGeneator.inl"
#endif // RANDOM_GENERATOR_H
:これは以下のように私のRandomGeneratorヘッダーファイルが見えるものである
: cppreferenceここにこのコード行があります
std::cout << std::generate_canonical<double, 10>(gen) << ' ';
私は作成して再帰しようとしていますnこの分布の静的インスタンス。テンプレート引数のRealTypeはデフォルトでdoubleに設定され、std::generate_canonical
で使用するのが優先され、std :: size_tは2番目のテンプレート引数のフィールドのビット数であり、3番目のテンプレート引数は渡されるRandomEngineジェネレータを表します。 Howe私はこの機能を適切に定義することに問題があります。私は私がこれを定義する他の方法を試してみたが、私は非常によく似たエラーが出るVS2015
1>------ Build started: Project: DieRoll, Configuration: Debug Win32 ------
1> RandomGenerator.cpp
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2988: unrecognizable template declaration/definition
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2143: syntax error: missing ';' before '&'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2365: 'std::generate_canonical': redefinition; previous definition was 'function'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\random(295): note: see declaration of 'std::generate_canonical'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2238: unexpected token(s) preceding ';'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(297): error C2059: syntax error: '&'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(304): error C2143: syntax error: missing ';' before '}'
1>c:\users\skilz80\documents\visual studio 2015\projects\dieroll\dieroll\randomgenerator.h(304): error C2238: unexpected token(s) preceding ';'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
からコンパイラエラーを取得しておきます。私は実際の作業を行うためにこれらの関数を必要としません。ユーザー定義のままにしておきます。準備が整ったRandomEngineとPreparedDistributionを簡単に作成するための簡単なユーザーインターフェイスを作成しています。ユーザーはまだ使用されているタイプのローカル変数を作成するオプションを持っています。この静的関数を適切に構築する方法に関する提案は感謝しています。
EDIT ildjarnのおかげで、std :: generate_canonicalはクラステンプレートではなく関数であることに言及してください。私がウェブサイトに戻ったとき、私は参照していました。小さな緑色のテキストの中に、クラステンプレートではなく機能テンプレートとしてリストされていました。私はそれが何であるかを知っているので、私はクラスからこれを省略し、それについて心配する必要はありません。これでコンパイルすることができなくなったときの混乱のビットがクリアされました。
EDIT
私は最終的には完全な私のクラスを持っており、主要なディストリビューションのすべてを組み込んでいるし、それらをテストしており、それらすべてが正しく動作するように見えます。 std::uniform_int
とstd::uniform_real
は、それぞれのディストリビューションの基本クラスであるため、削除しました。
これは、std :: uniform_int_distributionやstd :: uniform_real_distributionなどの他のディストリビューションと同じではないと言っていますか?私はそれが[0,1]の間の値を返すという事実以外にはそれほど多くを見つけませんでした。だから私はこの情報を使って推測しています。クラスから省略したり、関数を値を返す関数に変更してこの関数呼び出しを呼び出すことができます。 –
'generate_canonical'はディストリビューションではありません。私はそれがあなたに何の印象を与えたのか分かりません。あなたの意図がすべてのディストリビューションをサポートすることであるなら、 'generate_canonical'を無視することは確かに正しいことです。 : - ] – ildjarn
私はヘッダーを通過していました。そこに定義されています。また、このWebページもhttp://en.cppreference.com/w/cpp/numeric/randomで統一されているので、私が最初に集めていたものでした。 RealTypesでは[random]は[0,1]の間の値を返しますが、floatを使用すると、別のコンパイラで1を返すという警告があります。 ... –