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.
For a quick fix, use brace initialization:
In your original definition, the compiler thinks
genis a member function returning astd::mt19937that takes another function returning an instance of typerd, 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_deviceto seedgenonce, you can get rid of the member variable and use a temporary random device to constructgendirectly: