Reputation: 31
I'm in the process of moving a lot of oft-used functions into classes, and hit a snag that I can't explain. With the "STD::random-device rd" and "std::mt19937 gen(rd())" declarations in global-space everything works fine.
include <random>
std::random_device rd;
std::mt19937 gen(rd());
class randomGenerator
{
public:
float getRandomFloat(float lowerLimit, float upperLimit)
{
std::uniform_real_distribution<>dist(lowerLimit, upperLimit);
return (float)dist(gen);
}
};
randomGenerator myGenerator;
But if I move the declarations into the class definition, the compiler complains...
include <random>
class randomGenerator
{
public:
std::random_device rd;
std::mt19937 gen(rd());
float getRandomFloat(float lowerLimit, float upperLimit)
{
std::uniform_real_distribution<>dist(lowerLimit, upperLimit);
return (float)dist(gen);
}
};
randomGenerator myGenerator;
"E0757 member "randomGenerator::rd" is not a type name"
and
"E0304 no instance of overloaded function "std::uniform_real_distribution<_Ty>::operator() [with _Ty=double]" matches the argument list"
I've had similar trouble moving standalone variable declarations into other classes as well; seems almost hit-and-miss. Is there some reason why this doesn't always work? I can't see why some declarations (like above) will only work in global-space.
Upvotes: 3
Views: 95
Reputation: 4715
For a quick fix, use brace initialization:
class randomGenerator
{
public:
std::random_device rd;
std::mt19937 gen{rd()};
float getRandomFloat(float lowerLimit, float upperLimit)
{
std::uniform_real_distribution<>dist(lowerLimit, upperLimit);
return (float)dist(gen);
}
};
In your original definition, the compiler thinks gen
is a member function returning a std::mt19937
that takes another function returning an instance of type rd
, which does not exist. This is commonly known as most vexing parse.
Also, as Ted Lyngmo mentioned down in the comments, if you only use the std::random_device
to seed gen
once, you can get rid of the member variable and use a temporary random device to construct gen
directly:
class randomGenerator
{
public:
std::mt19937 gen{std::random_device{}()};
...
};
Upvotes: 10