封装std::mt19937到类时出现‘rd’不是类型的编译错误
解决类中随机数引擎初始化的编译错误
错误原因
你碰到的error: ‘rd’ is not a type是C++里的最令人头疼的解析问题——编译器把类内的std::mt19937 gen(rd());误判成了函数声明:它会认为gen是一个返回std::mt19937类型的函数,参数是一个返回rd类型的函数指针,但rd是你的类成员变量,根本不是类型,所以触发报错。
修正方案
有三种可行的修改方式,推荐用第三种(成员初始化列表),更符合C++编码规范:
方式1:用花括号初始化gen
把圆括号换成花括号,避免编译器的误解析:
#include <random> #include <iostream> class StdRandom { std::random_device rd; std::mt19937 gen{rd()}; // 替换圆括号为花括号 std::uniform_int_distribution<> distrib; public: StdRandom(int V) { std::uniform_int_distribution<> distribTmp(0, V); distrib = distribTmp; } int uniformInt() { return distrib(gen); } }; int main() { StdRandom rng(6); for (int n=0; n<10; ++n) std::cout << rng.uniformInt() << ' '; std::cout << '\n'; }
方式2:用双重括号包裹初始化表达式
通过额外的括号让编译器明确这是变量初始化,而非函数声明:
std::mt19937 gen((rd())); // 用双重括号包裹rd()
方式3:用构造函数的成员初始化列表(推荐)
把所有成员变量的初始化都放在构造函数的成员初始化列表中,既避免解析问题,又能提升效率(省去默认构造后再赋值的步骤):
#include <random> #include <iostream> class StdRandom { std::random_device rd; std::mt19937 gen; std::uniform_int_distribution<> distrib; public: // 成员初始化列表完成所有变量的初始化 StdRandom(int V) : gen(rd()), distrib(0, V) {} int uniformInt() { return distrib(gen); } }; int main() { StdRandom rng(6); for (int n=0; n<10; ++n) std::cout << rng.uniformInt() << ' '; std::cout << '\n'; }
额外说明
- 类成员的初始化顺序是按它们在类中声明的顺序执行的,而非初始化列表里的顺序,所以要保证
rd在gen之前声明,这样初始化gen时rd已经就绪。 - 用成员初始化列表初始化
distrib,比在构造函数体内赋值更高效,因为省去了默认构造的步骤。
内容的提问来源于stack exchange,提问作者qqqqq
相关产品推荐
相关产品推荐

