std::ratio_multiply是C++11引入的编译期ratio乘法模板别名,用于在类型层面相乘两个std::ratio并自动约简,所有运算在编译期完成且零运行时代价。
是的, std::ratio_multiply 是 C++11 引入的编译期有理数运算工具,用于在类型层面相乘两个 std::ratio,结果仍是 std:: 类型,所有计算(分子、分母约分)都在编译期完成,零运行时代价。
它不是函数,而是一个模板别名(C++11 起定义为 template),所以不能传变量,只能传字面量 ratio 类型。
ratio_multiply::num 中 r1 或 r2 是变量 —— 编译失败,因为模板参数必须是类型std::kilo、std::mega、或自定义的 std::ratio
std::gcd 和 std::lcm(C++17 起)对分子分母做最大公约数约简,确保结果最简必须保证两个操作数都是 std::ratio 类型(包括标准库预定义的如 std::milli),且结果可表示为整型常量表达式(即不溢出 intmax_t)。
示例中所有内容都可在 constexpr 上下文使用:
using r1 = std::ratio<2, 3>; using r2 = std::ratio<5, 4>; using product = std::ratio_multiply; // 等价于 ratio<10, 12> → 自动约简为 ratio<5, 6> static_assert(product::num == 5, ""); static_assert(product::den == 6, "");
// 复合使用:毫秒 × 千 = 秒 using ms = std::milli; using k = std::kilo; using ms_times_k = std::ratio_multiply
; // milli × kilo = ratio<1, 1> → 1:1,即 1 毫秒 × 1000 = 1 秒 static_assert(ms_times_k::num == 1 && ms_times_k::den == 1, "");
ratio 相乘),编译器行为未定义,多数会报错或静默截断(取决于实现)std::ratio_multiply 的等效计算是:ratio<:num r2::num gcd r1::den r2::den>,但你完全不用手算double 或浮点字面量参与——std::ratio 只接受整型模板参数它们彼此独立,但组合使用时容易忽略约简时机和中间类型的精度限制。
std::ratio_add 要求先通分(分母取 lcm),再加分子;若 A::den 和 B::den 很大,lcm 可能溢出,而 ratio_multiply 不涉及 lcm,相对更“安全”ratio_multiply, C> 是合法的,但建议用 using 拆解,否则嵌套过深影响可读性和错误定位ratio_power,要算平方得写两次 ratio_multiply,三次就再套一层std::gcd/std::lcm 未标准化,部分老编译器(如 GCC 4.9)可能用内部实现,但 ratio_multiply 本身仍可用主要出现在单位系统建模、硬件寄存器配置、定时器周期换算等要求**绝对编译期确定性**的场景。
ratio 运算,生成最终频率类型,供 std::chrono::duration 使用ratio(1 MHz),经两级分频 ratio 和 ratio,用 ratio_multiply 链式组合得到最终采样间隔ratio 替代 #define CLK_DIV 256 或 constexpr double clk_div = 256.0;,获得类型安全与编译期检查ratio_multiply 此时无用武之地最容易被忽略的一点:std::ratio_multiply 的结果类型名极长(尤其嵌套后),调试时看编译错误信息会非常痛苦;建议始终用 using 给中间结果起短名,并搭配 static_assert 校验关键值。