提问人:Ростислав Романець 提问时间:6/12/2023 最后编辑:Jan SchultkeРостислав Романець 更新时间:6/12/2023 访问量:95
如何初始化静态随机生成器数据成员?
How do I initialize a static random generator data member?
问:
我有类,我不知道如何正确初始化其静态数据成员。Random
// random.h
#pragma once
#include <random>
class Random
{
private:
static std::uniform_real_distribution<float> sDistribution_;
static std::mt19937 sGenerator_;
};
// random.cpp
#include "random.h"
std::mt19937 Random::sGenerator_(std::random_device()); // error here
std::uniform_real_distribution<float> Random::sDistribution_(0.0f, 1.0f);
当我编译它时,我收到一个错误:
声明与 不兼容。
std::mt19937
如何正确初始化此成员?
答:
5赞
Jan Schultke
6/12/2023
#1
std::mt19937 Random::sGenerator_(std::random_device());
是最令人烦恼的解析的实例。 您想执行直接初始化,但实际上您:
声明为函数,获取指向不带参数的函数的指针,并返回
std::random_device
。该函数返回std::mt19937
。Random::sGenerator_
Random::sGenerator_
编译器是这么想的,它与 的原始定义相冲突,该定义将其声明为 std::mt19937
类型的静态数据成员。Random::sGenerator_
解决方案很简单:std::random_device
是一个类型,而不是一个函数,所以你需要在调用它之前初始化它,比如:
std::mt19937 Random::sGenerator_{std::random_device{}()};
// or
std::mt19937 Random::sGenerator_{std::random_device()()};
// or
std::mt19937 Random::sGenerator_(std::random_device{}());
通常,某些人认为首选列表初始化是很好的做法,因为它避免了这种解析歧义。请注意,当一个类型有一个构造函数采用 std::initializer_list
时,它的工作方式会有所不同(对于我们使用的任何类型来说都不是问题)。
从 C++17 开始
您还可以初始化类中的静态数据成员,例如:
class Random
{
private:
static inline std::uniform_real_distribution<float> sDistribution_{0, 1};
static inline std::mt19937 sGenerator_{std::random_device{}()};
};
注意:如果你的类所做的只是存储静态数据成员,那么它可能只是一个命名空间
,而不是一个类
。
评论
std::random_device()
std::random_device{}()
random_device