-1

I'm attempting to use a seeded random_shuffle to simply shuffle a vector, before I use it. I tested this out by doing

#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <bits/stdc++.h>


using namespace std;

int seed;
int rng(int i)
{
    srand(seed);
    return rand()%i;
}
int main()
{
    vector<int> myVec;
    cin >> seed;

for (int i = 0; i < 10; ++i)
    myVec.push_back(i);

for (auto it = myVec.begin(); it != myVec.end(); ++it)
    cout << *it;
cout << endl;
random_shuffle(myVec.begin(), myVec.end(), rng);

for (auto it = myVec.begin(); it != myVec.end(); ++it)
    cout << *it;
}

and it worked just fine. This lets me enter an int for the seed, and then prints out the before and after. However, when I tried to insert it into a class and run a build task with VSCode, it exploded.

class Test
{
public:
    Test(int seed)
    {
        random = seed;
        for (int i = 0; i < 10; ++i)
        myVec2.push_back(i);

       random_shuffle(myVec2.begin(), myVec2.end(), r);

    }
private:
    vector<int> myVec2;
    int random;

    int r(int i)
    {
        srand(random);
        return rand()%i;
    }
};

Here's the errors that came up:

25:54 required from here
error: must use '.*' or '->*' to call pointer-to-member function in '__rand (...)', e.g. '(... ->* __rand) (...)'
 4619 |    _RandomAccessIterator __j = __first + __rand((__i - __first) + 1);

Why is random_shuffle functioning correctly in main(), but not a class?

JebLab
  • 28
  • 7

1 Answers1

3

rng is a global function. r is a member function of a class.

Consider it from the viewpoint of random_shuffle. When it wants to call r, on what object will it call it? Since it knows nothing about your class it simply won't be able to. This is what the error message is trying to tell you (clumsily).

One typical way would be to make int r(int i) static. But then, you won't have access to random. A more modern way would be to use a lambda:

    random_shuffle(myVec2.begin(), myVec2.end(), [this](int i){return r(i);} );

Basically, the lambda is an object wrapping a function that calls r(i) for you, but on the this pointer.

As @cigien recommends, using shuffle instead would be a very good idea as the standard changed a long time ago. See: https://en.cppreference.com/w/cpp/algorithm/random_shuffle This would remove the need for r or rng altogether and get rid of this question :-)

Jeffrey
  • 11,063
  • 1
  • 21
  • 42
  • 2
    Please suggest that `shuffle` be used instead. `random_shuffle` has been deprecated for 7 years, and was removed 4 years ago. – cigien Apr 30 '21 at 02:11
  • That compiles, and seems to make everything work correctly. I'll have to study and understand lambdas further, this was my first semester with C++ and I didn't know much about them. As for switching random_shuffle for shuffle, I'll look into that! – JebLab Apr 30 '21 at 02:35