In my programming I need to create a user-defined number of ublas vectors. I would like to do this with std::generate
. However I get compiler errors that make it impossible for me.
The code I'm using:
for (size_t a_= 0; a_ < p_; a_++)
{
ublas::vector<double> next_vhat(size_of_vec);
std::generate(next_vhat.begin(), next_vhat.end(), mygen.give_rnd);
v_hat_.push_back(next_vhat);
}
I had to create a class
specifically for the function call, since std::generate
won't allow me to use a function with an argument as the third argument ("gen", see here. I need the numbers to be normal distributed, so the function call to the distribution function must contain, as an argument, the random number generator. Since it didn't allow me to call it with the argument, I had to write a class to do this for me.
The class I have written:
class RandGen
{
public:
RandGen()
: generator()
, norm_dist(0.0,1.0)
, random_seed(static_cast<unsigned>(std::time(NULL)))
{}
double give_rnd() { return (double) norm_dist(generator); }
private:
base_gen_t generator;
boost::random::normal_distribution<double> norm_dist; //Standard normal distribution
unsigned random_seed;
};
The error I'm getting
When trying to compile the whole thing, I get the following error:
error: cannot convert ‘RandGen::give_rnd’ from type ‘double (RandGen::)()’ to type ‘double (RandGen::*)()’
I have no idea what the compiler wants me to do here, or why it has so much trouble with this at all. Any advice is very appreciated.
You need to pass a callable object. That is, either a function pointer (not a member function pointer, which is what mygen.give_rnd
is) or an object of a class that overloads operator()
. You can just change your function give_rnd
to this:
double operator()() { return (double) norm_dist(generator); }
And then, just pass your object directly to std::generate
std::generate(..., ..., mygen);
If, for some reason, you wanted to keep your RandGen
class as it is, you would need to wrap it in another functor or lambda:
std::generate(..., ..., [&mygen]() { return mygen.give_rnd(); });