2017-07-02 4 views
5

सी ++ 11 से पहले, मैंने से rand() का उपयोग किया था और main() फ़ंक्शन (उदाहरण के लिए) में जनरेटर को बीज (या नहीं) चुनना बहुत आसान था, फिर पुस्तकालय में उपयोग करें लाइब्रेरी में कहीं फ़ंक्शन द्वारा उत्पन्न यादृच्छिक संख्या । कोड इस तरह देखा:सी ++ 11 में यादृच्छिक संख्या: क्या कोड के एक स्थान पर जनरेटर को बीज करने का एक आसान तरीका है, फिर इसे विभिन्न कार्यों में उपयोग करें?

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() अपडेट करना चाहता हूं। मैंने पहले से ही here और there उदाहरण पढ़ और देखे हैं, लेकिन मुझे नहीं लगता कि इसे मेरे तीन मॉड्यूल में कैसे अनुकूलित किया जाए। निश्चित रूप से, GetRandDoubleBetween0And1() अंदर इंजन बोने ऐसा करना सही नहीं है ...

क्या आपको लगता है मैं main() से वरीयता प्राप्त इंजन UseSomeRandomness() को LibraryA में, तो UseSomeRandomness() से GetRandDoubleBetween0And1() को LibraryB में पारित करने के लिए करना होगा? या क्या कोई आसान तरीका है?

उत्तर

5

आपको लगता है मैं वरीयता प्राप्त इंजन मुख्य() से UseSomeRandomness() के लिए LibraryA में, तो UseSomeRandomness() GetRandDoubleBetween0And1() करने के लिए से LibraryB में पारित करने के लिए होगा है?

हां।

आप जनरेटर को एक बार तुरंत चालू करते हैं, फिर किसी भी संदर्भ में इसका संदर्भ या सूचक पास करते हैं।

यह किसी अन्य संसाधन से निपटने जैसा है।

+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 मतलब है कि आप एक हेडर फाइल में रख सकते हैं और संकलक स्थिर वस्तुओं जो यह लिंक समय में हल होगा की केवल एक प्रतिलिपि बनाएगा। हालांकि यदि आप इसे गतिशील पुस्तकालय में उपयोग करते हैं तो आपको अलग-अलग प्रतियां मिलेंगी। उस स्थिति में आप इस फ़ंक्शन को अपनी लाइब्रेरी में डाल सकते हैं और फ़ंक्शन का उपयोग करने वाले प्रत्येक प्रोग्राम से लिंक कर सकते हैं।

thread_local थ्रेड सुरक्षा (प्रति थ्रेड एक यादृच्छिक जनरेटर) सुनिश्चित करता है और स्थिर होने पर उन्हें केवल एक बार प्रारंभ किया जाता है।

+2

Fwiw, 'thread_local' का अर्थ' स्थिर 'है। –

0

मेरी 'यादृच्छिक' लाइब्रेरी सी ++ 11 यादृच्छिक कक्षाओं के आसपास एक उच्च सुविधाजनक रैपर प्रदान करती है। आप लगभग सभी चीज़ों को सरल 'पाने' विधि के साथ कर सकते हैं।

आपके उपयोग के मामले में आप स्थिर एपीआई के साथ ऑटो बीज वाले random_static wrapper का उपयोग कर सकते हैं।

उदाहरण:

#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

संबंधित मुद्दे