How do I pass a C++11 random number generator to a function?

后端 未结 4 2247
伪装坚强ぢ
伪装坚强ぢ 2020-12-15 20:17

Do they all inherit from a base class? Do I have to use templates?

(I am referring to these http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c15319/)

相关标签:
4条回答
  • 2020-12-15 20:35

    They don't all inherit from a base (which is a little surprising), but it doesn't matter because that's not how C++ functors work.

    For arbitrary RNGs of a single given type, you got it right as (now) posted.

    If you mean, how do I define a function which accepts any random number generator as an argument.

    template< class RNG > // RNG may be a functor object of any type
    int random_even_number( RNG &gen ) {
        return (int) gen() * 2;
    }
    

    You don't need to use any more templates than this, because of type deduction.


    Defining one function to accept different RNG's is trickier because semantically that requires having a common base type. You need to define a base type.

    struct RNGbase {
        virtual int operator() = 0;
        virtual ~RGNBase() {};
    };
    
    template< class RNG >
    struct SmartRNG : RNGBase {
        RNG gen;
    
        virtual int operator() {
            return gen();
        }
    };
    
    int random_even_number( RNGBase &gen ) { // no template
        return (int) gen() * 2; // virtual dispatch
    }
    
    0 讨论(0)
  • 2020-12-15 20:40

    What worked for me was using an std::function:

    #include <functional>
    #include <random>
    
    void exampleFunction(std::function<int()> rnd) {
        auto randomNumber = rnd();
    }
    
    std::minstd_rand rnd;
    exampleFunction([&rnd](){ return rnd(); });
    
    // This won't work as it passes a copy of the object, so you end up with the same
    // sequence of numbers on every call.
    exampleFunction(rnd);
    

    You're not really passing around the random object, just a method to call the object's operator (), but it achieves the same effect.

    Note that here the precision of the random number generator's return value may be reduced as the std::function is declared as returning an int, so you may want to use a different data type instead of int depending on your need for precision.

    0 讨论(0)
  • 2020-12-15 20:48

    Wrap it in a class or functor that fit your needs?

    0 讨论(0)
  • 2020-12-15 20:52

    I suggest two methods: Function Objects and Function Pointers. In either case, enable your class to receive a Function Object or a Function Pointer to the random number generator.

    With a Function Object, you can define a base class, and have your receiving class implement functions that require a pointer to the base function object class. This gives you more freedom in defining many different function objects without changing the interface of the receiving class.

    0 讨论(0)
提交回复
热议问题