std::uniform_int_distribution是c++11提供的均匀整数分布工具,需配合随机引擎(如mt19937)使用,构造时指定闭区间[a,b],避免rand()%n的模偏差,确保严格等概率且可复现。

std::uniform_int_distribution 是 C++11 起标准库提供的真正均匀整数随机分布工具,它本身不生成随机数,而是对 std::random_device 或 std::mt19937 等引擎输出的伪随机位序列做「映射」,确保落在指定整数区间内严格等概率。直接用 rand() % n 会因模偏差导致非均匀,这点必须避开。
怎么正确构造和使用 uniform_int_distribution
核心是两步:先选一个合适的随机数引擎(推荐 std::mt19937),再用闭区间 [a, b] 构造分布对象。注意:参数是「包含两端」的闭区间,不是左闭右开。
常见错误写法:uniform_int_distribution<int>(0, 10)</int> 生成的是 0 到 10(含)共 11 个整数,不是 0~9。
实操建议:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 用
std::random_device初始化std::mt19937的种子,避免默认种子全为 0 - 分布对象可复用,不要每次生成都重新构造(有轻微开销)
- 若需多线程安全,每个线程应持有独立的引擎实例(
mt19937非线程安全)
std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<int> dist(1, 6); // 模拟掷骰子:1~6 均匀 int roll = dist(gen); // 调用一次,返回一个 int</int>
为什么不能直接用 rand() 或 std::rand()
rand() 返回值范围通常为 [0, RAND_MAX](常为 32767),当用 rand() % 100 生成 0~99 时,前 32700 个数能被整除,但剩下 67 个余数只覆盖 0~66 —— 导致 0~66 的概率略高于 67~99。这种模偏差在 uniform_int_distribution 内部已被规避(它用拒绝采样或更优算法)。
此外:rand() 是遗留 C 函数,无状态、不可预测、不可重现,且不保证均匀性;而 std::mt19937 + uniform_int_distribution 是可复现、可移植、符合统计要求的组合。
生成不同范围或类型的整数要注意什么
类型和范围必须匹配,否则行为未定义或隐式截断:
- 若用
uniform_int_distribution<long long></long>但引擎最大值小于LLONG_MAX,仍能工作,但高位永远为 0 - 区间端点必须满足
a ,否则构造时抛 <code>std::invalid_argument - 若
b - a > std::numeric_limits<inttype>::max()</inttype>(比如int分布却设[0, 3000000000]),会溢出,结果不可靠 - 负数范围完全合法:
uniform_int_distribution<int>(-5, 5)</int>生成 -5 到 5 共 11 个整数
最易被忽略的一点:分布对象(uniform_int_distribution)是轻量级的,但它依赖引擎的状态。如果引擎被重复初始化(比如函数内每次都 mt19937 gen(rd())),会导致大量重复序列——尤其在快速连续调用时。真要复现结果,应固定种子,如 mt19937 gen(42)。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










