将成员函数放在定义中

Fai*_*ght 3 c++ class class-members

我正在将许多常用函数转移到类中,但遇到了我无法解释的障碍。通过全局空间中的“STD::random-device rd”和“std::mt19937 gen(rd())”声明,一切正常。

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;
Run Code Online (Sandbox Code Playgroud)

但是如果我将声明移到类定义中,编译器会抱怨......

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;
Run Code Online (Sandbox Code Playgroud)

"E0757 member "randomGenerator::rd" is not a type name""E0304 no instance of overloaded function "std::uniform_real_distribution<_Ty>::operator() [with _Ty=double]" matches the argument list"

我在将独立变量声明移动到其他类时也遇到了类似的麻烦;看起来几乎是碰碰运气。有什么原因导致这并不总是有效吗?我不明白为什么某些声明(如上面)只能在全局空间中起作用。

Fat*_*KIR 10

要快速修复,请使用大括号初始化:

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);
    }
};
Run Code Online (Sandbox Code Playgroud)

在您的原始定义中,编译器认为gen是一个返回 a 的成员函数std::mt19937,它接受另一个返回类型 实例的函数rd,该实例不存在。这通常被称为最令人烦恼的解析

另外,正如 Ted Lyngmo 在评论中提到的,如果你只使用一次std::random_device种子gen,你可以摆脱成员变量并使用临时随机设备gen直接构造:

class randomGenerator
{
public:
    std::mt19937 gen{std::random_device{}()};
    ...
};
Run Code Online (Sandbox Code Playgroud)