Search code examples
c++randomtr1const-correctnessconst-cast

C++ TR1: What is the proper way to use a uniform distribution to generate a random number in a const method?


I have a simple const method that wants to generate a random number

int Object::const_method() const {
    std::tr1::uniform_int<int> uni(0,100);
    // do some calculation
   return result;
}

This results in your standard (if templafied) const violation error

/usr/lib/gcc/x86_64-unknown-linux-gnu/4.5.1/../../../../include/c++/4.5.1/tr1/random.tcc:910:4: error: passing ‘const std::tr1::mersenne_twister’ as ‘this’ argument of ‘result_type std::tr1::mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, __b, __t, __c, __l>::operator()() [with _UIntType = long unsigned int, int __w = 32, int __n = 624, int __m = 397, int __r = 31, _UIntType __a = 2567483615ul, int __u = 11, int __s = 7, _UIntType __b = 2636928640ul, int __t = 15, _UIntType __c = 4022730752ul, int __l = 18, result_type = long unsigned int]’ discards qualifiers

Is this doable without a const_cast on this?


Solution

  • Make your mersenne_twister object mutable within your class. Without seeing all your code, (especially the do_something part), we can't be certain, but I'm guessing that you have an object within your class of type merseene_twister which you are using a function of which is not a const function itself. This is causing the error in your class, because your const function is calling a function on merseen_twister that may change it, violating your const signature.

    // I'm using this as an example.  Yours may differ
    typedef std::mersenne_twister<unsigned int, 32, 624, 
        397, 31, 0x9908b0df, 11, 7, 0x9d2c5680, 
        15, 0xefc60000, 18> MerTwister;
    
    class Object 
    {
        public:
    
        int Object::const_method() const 
        {
           std::tr1::uniform_int<int> uni(0,100);
    
           // do some calculation using the MerTwister object
           return result;
        }
    
    
        private:
        mutable MerTwister twister;
    };