2016-04-15 6 views
-1

インスタンスをインスタンス化しないクラスで作業しています。それは保護されたコンストラクタを持ち、すべてのメソッドは静的です。このクラスでは、さまざまなランダムなエンジンへの呼び出しを簡素化しています。<random>私は、異なる配信タイプに対して同じことをする同様のクラスを持っています。私のエンジンへの静的な呼び出しはすべて、うまく動作し、複数の方法でそれらをシードすることができます。私は現在、さまざまなディストリビューションを扱うためにコンパニオンクラスに取り掛かる過程にあります。これまで私はstd::uniform_intstd::uniform_int_distributionstd::uniform_realstd::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_intstd::uniform_realは、それぞれのディストリビューションの基本クラスであるため、削除しました。

答えて

1

std::generate_canonicalはタイプではありません。

+0

これは、std :: uniform_int_distributionやstd :: uniform_real_distributionなどの他のディストリビューションと同じではないと言っていますか?私はそれが[0,1]の間の値を返すという事実以外にはそれほど多くを見つけませんでした。だから私はこの情報を使って推測しています。クラスから省略したり、関数を値を返す関数に変更してこの関数呼び出しを呼び出すことができます。 –

+2

'generate_canonical'はディストリビューションではありません。私はそれがあなたに何の印象を与えたのか分かりません。あなたの意図がすべてのディストリビューションをサポートすることであるなら、 'generate_canonical'を無視することは確かに正しいことです。 : - ] – ildjarn

+0

私はヘッダーを通過していました。そこに定義されています。また、このWebページもhttp://en.cppreference.com/w/cpp/numeric/randomで統一されているので、私が最初に集めていたものでした。 RealTypesでは[random]は[0,1]の間の値を返しますが、floatを使用すると、別のコンパイラで1を返すという警告があります。 ... –

関連する問題