2017-07-02 7 views
5

C++ 11以前は<cstdlib>rand()を使用していましたが、main()関数でジェネレータをシード(または生成しない)することは非常に簡単でした。たとえば、libraryBのどこかの関数で生成された乱数。コードは次のように見えた:C++での乱数11:コードの1つの場所にジェネレータをシードして別の関数で使用する簡単な方法はありますか?

LibraryB(乱数、昔ながらの方法を生成します):

#include <cstdlib> // rand, RAND_MAX 
double GetRandDoubleBetween0And1() { 
    return ((double)rand())/((double)RAND_MAX); 
} 

主なプログラム:

#include <cstdlib> // srand 
#include <ctime> // time, clock 
int main() { 
    bool iWantToSeed = true; // or false, 
          // decide HERE, applies everywhere! 
    if(iWantToSeed){ 
     srand((unsigned)time(0) + (unsigned int)clock()); 
    } 
    // (...) 
} 

LibraryAは(に応じて生成された、LibraryBから乱数を使用していますmain()で与えられる種):

#include "../folderOfLibraryB/Utils_random.h" // GetRandDoubleBetween0And1 
void UseSomeRandomness(){ 
    for(int i = 0; i < 1000000; i++){ 
     double nb = GetRandDoubleBetween0And1(); 
     // (...) 
    } 
} 

簡単ですね。

#include <random>で利用可能なC++ 11標準を使用してGetRandDoubleBetween0And1()を更新したいと思います。私はすでにherethereの例を読んで見ましたが、3つのモジュールにどのように適合させるかはわかりません。確かに、GetRandDoubleBetween0And1()の内側にエンジンを播種して行うには正しいことではありません...

私はLibraryBで、その後UseSomeRandomness()からGetRandDoubleBetween0And1()に、LibraryAにmain()からUseSomeRandomness()にシードされたエンジンを渡す必要がありますと思いますか?それとも簡単な方法がありますか? LibraryBでLibraryAで、その後、UseSomeRandomness()からGetRandDoubleBetween0And1へ

答えて

5

あなたは私が(メインからシードされたエンジンを渡す必要がありますと思います)UseSomeRandomnessに()()?

はい。

ジェネレータを一度インスタンス化してから、参照またはポインタを使用したいコンテキストに渡します。

これは他のリソースと同様です。

+2

私の既存のコードのためにどのような悪いニュース! – Georg

4

あなたはこのような何かを行うことができます。

#include <random> 

inline double GetRandDoubleBetween0And1() { 
    thread_local static std::mt19937 gen{std::random_device{}()}; 
    thread_local static std::uniform_real_distribution pick{0.0, 1.0}; 
    return pick(gen); 
} 

ビーイングinlineあなたはヘッダファイルにそれを置くことができ、コンパイラは、リンク時に解決される静的オブジェクトのコピーを1つだけ作成することを意味します。ただし、ダイナミックライブラリで使用すると、異なるコピーが作成されます。その場合、この関数を独自のライブラリに配置し、関数を使用する各プログラムにリンクすることができます。

thread_localは、スレッドの安全性(スレッドごとに1つのランダムジェネレータ)を保証し、静的であるため、一度しか初期化されません。

+2

Fwiw、 'thread_local'は' static'を意味します。 –

0

私の「ランダム」ライブラリは、C++ 11のランダムなクラスの周りに便利なラッパーを提供します。単純な「取得」方法でほとんどすべてのことを行うことができます。

静的APIを使用して自動シードされたrandom_staticラッパーを使用できます。

例:

#include "effolkronium/random.hpp" 

using Random = effolkronium::random_static; 

auto Func() { 
    return Random::get(-10, 10) 
} 

auto Func2() { 
    return Random::get(-10, 10) 
} 

int main() { 
    // Seed static internal engine 
    Random::seed(MySuperSeed); 

} 

これは、単一のヘッダのみのライブラリです。

githubのページをご覧ください: https://github.com/effolkronium/random

関連する問題