Home > OS >  I want to use my own random function with std::shuffle, but it is not working
I want to use my own random function with std::shuffle, but it is not working

Time:11-08

I get an error when I use myRand::RandInt instead of something like default_random_engine. But I don't understand how am I supposed to implement the random_engine function. What I've done works well with std::random_shuffle, but I understand that this function was deprecated, and std::shuffle is preffered.

i am trying to get this to work:

int main()
{
    std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    std::shuffle (v.begin(), v.end(), myRand::RandInt);
  
    return 0;
}

i've defined a namespace to implement the funcions:

namespace myRand{
    
    bool simulatingRandom = false;
    std::vector<int> secuenciaPseudoRandom = {1,0,1,0};
    long unsigned int index = 0;
    
    int Rand() {
        //check
        if (index > secuenciaPseudoRandom.size() - 1 ) {
            index = 0;
            std::cout << "Warning: myRand resetting secuence" << std::endl;
        };
        
        if (simulatingRandom) {
            //std::cout << "myRand returning " << secuenciaPseudoRandom[i] << std::endl;
            return secuenciaPseudoRandom[index  ];
        }
        else {
            return rand();
        }
    }


    // works as rand() % i in the case of simulatingRandom == false
    int RandInt(int i) {

        return Rand() %i;
    }


}

Basically I want to be able to change between simulating random and true random easily for testing purposes. So that in my main code I can do the testing with simulatingRandom set to true and then change it to false. Maybe there is a better way to do testing of functions that involves random. If so, I am open to any suggestions.

CodePudding user response:

the last argument to std::shuffle must meet the requirements of UniformRandomBitGenerator. The generator should be an object not a function. For example a minimal implementation would be:

struct RandInt
{
    using result_type = int;

    static constexpr result_type min()
    {
        return 0;
    }

    static constexpr result_type max()
    {
        return RAND_MAX;
    }

    result_type operator()()
    {
        return Rand();
    }
};

You can then call it as:

std::shuffle (v.begin(), v.end(), myRand::RandInt());

Note that you'l need to adjust the values of min and max if you set your simulatingRandom value to true to match the expected values. If they don't match the true values std::shuffle probably wont be as random as it should be.

Have to finish with the usual reminder not to use rand in modern code: Why is the use of rand() considered bad? especially without calling srand first. The use of rand is the main reason std::random_shuffle is deprecated.

  • Related