You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C++23 GCC13.2.0中如何结合std::lcm与std::ranges::fold_left?求更佳方案

std::lcm与std::ranges::fold_left结合使用的问题解答

尝试将C++23中的std::lcm与std::ranges::fold_left结合使用时,在GCC 13.2.0及cppinsights.io环境下编译失败。对比std::plus、std::multiplies与std::lcm的函数签名后定位了问题根源,现针对以下三个问题给出解答:

1. 推荐的标准实现方式是什么?

最直接的标准方案是用lambda表达式包装std::lcm,适配fold_left的调用要求,代码示例:

#include <numeric>
#include <ranges>
#include <vector>

int main() {
    std::vector<int> nums{4, 6, 8};
    auto result = std::ranges::fold_left(nums, 1, [](auto a, auto b) {
        return std::lcm(a, b);
    });
}

这种写法完全符合C++23标准,既能避开签名不兼容问题,又保持了代码的简洁性和可读性。

2. 是否必须自行实现结构体?

不需要。除了lambda方案,你也可以用std::bind_front或者std::bind做适配,但lambda的可读性和易用性更优。如果确实需要复用这个适配逻辑,自定义仿函数结构体是可选方案,但绝非必须——lambda已经能覆盖绝大多数场景的需求。

3. 为何这些接口设计不一致?

核心原因是std::lcm(以及std::gcd)的设计定位和std::plus、std::multiplies这类算术仿函数完全不同:

  • std::plus、std::multiplies是可调用对象模板,本身是仿函数类型,实例化后可以直接作为二元函数对象传递给算法,它们的operator()签名是(const T&, const T&),完美匹配fold_left这类算法对二元操作的要求。
  • 而std::lcm是普通函数模板,它的签名是template<typename M, typename N> constexpr std::common_type_t<M,N> lcm(M m, N n);。直接传递std::lcm时,编译器无法推导模板参数(因为fold_left需要的是一个可调用对象,而非模板本身)。另外,std::lcm有额外的前置条件(输入必须是非负整数),这也是和普通算术操作设计考量不同的地方。

内容的提问来源于stack exchange,提问作者Torsten Knodt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:20:14