std::ratio 是编译期有理数类型,仅支持模板实例化阶段的类型级约分与运算,结果为新 std::ratio 类型,需通过 num/den 静态成员提取 constexpr 值。

std::ratio 是编译期有理数,不是运行时计算工具
它根本不会“做运算”,只是提供一套类型级别的分数表示和约分机制。所有“运算”都发生在模板实例化阶段,结果是另一个 std::ratio 类型,而非数值。你拿到的是类型,不是值;想提取分子分母得靠 num 和 den 静态成员。
加减乘除用 ratio_add、ratio_subtract 等元函数
标准库提供了 std::ratio_add、std::ratio_multiply 等别名模板,它们接收两个 std::ratio 类型,返回约分后的结果类型。注意:这些不是函数调用,不能传变量,只能传字面量类型的 std::ratio。
-
std::ratio_add<:ratio>, std::ratio>::type</:ratio>得到std::ratio -
std::ratio_multiply<:ratio>, std::ratio>::type</:ratio>得到std::ratio(自动约分) - 若分母为 0 或溢出(如分子超出
intmax_t),编译失败,报错类似static_assert failed due to requirement 'den != 0'
不能直接用整数字面量,必须包装成 std::ratio
你不能写 ratio_add,也不能写 ratio_add<:ratio>, ...></:ratio> —— C++ 不允许浮点或未包装的整数作为模板非类型参数(C++20 前)。所有输入必须是显式构造的 std::ratio<n d></n> 类型。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 错误:
std::ratio_add<:ratio>, std::ratio></:ratio>(缺分母,默认为 1,但语义不是“1/2”) - 正确:
std::ratio表示 1⁄2,std::ratio等价于std::ratio - 大数要小心:
std::ratio可能触发编译器整型常量溢出(取决于intmax_t位宽)
提取结果要用 ::num / ::den,且是静态 constexpr 值
运算结果类型本身不带运行时值,但它的嵌套静态成员 num 和 den 是 constexpr intmax_t,可在编译期用于数组大小、模板参数等。
constexpr auto r = std::ratio_add<:ratio>, std::ratio>::type{};
static_assert(r::num == 11 && r::den == 12, "should be 11/12");
int arr[r::num]; // 合法:r::num 是编译期常量
</:ratio>
注意:C++17 起 r::num 可直接用,无需 decltype(r)::num;但若用在模板参数中(如 std::array<int r::num></int>),仍需确保其为 ICE(integer constant expression),而 std::ratio 的 num/den 满足该要求。
真正容易被忽略的是:所有运算都依赖整数算术的精确性与溢出行为——它不处理近似、不支持无理数、也不做浮点模拟。一旦分子分母超出 intmax_t 表达范围,就是硬编译失败,没有 fallback。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










