0

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 preferred.

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 functions:

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.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
MarcosP
  • 5
  • 3
  • In cppreference says that std::shuffle takes URBG as its 3rd parameter. but I cannot find any information about what that is or how to implement it. – MarcosP Nov 05 '22 at 18:31
  • 4
    From https://en.cppreference.com/w/cpp/algorithm/random_shuffle under "Type requirements": "`std::remove_reference_t` must meet the requirements of [UniformRandomBitGenerator](https://en.cppreference.com/w/cpp/named_req/UniformRandomBitGenerator)." – Kevin Nov 05 '22 at 18:34
  • By the way the random number generators in the standard library are simulating random.For a truly random number you need a hardware device. In fact if you start with the same seed you can replicate the 'random' sequence as often as you want by the way. – QuentinUK Nov 05 '22 at 18:58

1 Answers1

4

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.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60