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

基于整数范围模板参数生成笛卡尔积的C++实现问题

解决C++中编译期模板参数到运行时映射的重复组合问题

问题场景

我正在使用一个第三方库,它提供的Numeric类必须以**precision(精度)和scale(小数位数)**作为模板参数。但我的开发场景中,这两个参数要到运行时才能确定,因此需要创建所有合法参数组合到对应模板函数的运行时映射。

要求覆盖(0, 38]范围内所有满足scale <= precision的参数组合,最终映射形式如下:

mapping = {
  <38, 38>: []() { /* 处理Numeric<38, 38> */ },
  <38, 37>: []() { /* 处理Numeric<38, 37> */ },
  ...
  <1, 1>: []() { /* 处理Numeric<1, 1> */ },
  <1, 0>: []() { /* 处理Numeric<1, 0> */ },
}

之前的实现代码存在递归调用导致的重复组合问题,输出中出现了重复的(3,3)和(1,0),需要修复为无重复的合法组合,且方案需兼容C++17。

解决方案

核心问题是原递归逻辑存在交叉调用,导致同一参数组合被多次处理。我们可以通过分层递归的方式,先遍历所有合法的precision值,再对每个precision遍历所有合法的scale值,确保每个组合只被处理一次。

代码实现

1. 定义映射类型

#include <map>
#include <functional>

using funcMapType = std::map<std::pair<int, int>, std::function<void(void)>>;

2. 实现单个Precision对应的所有Scale插入逻辑

// 递归插入单个Precision下的所有Scale(从CurrentScale到0)
template<int Precision, int CurrentScale>
struct ScaleInserter {
    static void insert(funcMapType& func_map) {
        // 插入当前(Precision, CurrentScale)组合,替换为实际业务逻辑
        func_map.emplace(std::make_pair(Precision, CurrentScale), [](){
            // 示例:实例化Numeric<Precision, CurrentScale>并处理
            // Numeric<Precision, CurrentScale> num;
            // ... 业务代码
        });
        // 递归处理更小的Scale
        ScaleInserter<Precision, CurrentScale - 1>::insert(func_map);
    }
};

// 递归终止条件:当CurrentScale < 0时停止
template<int Precision>
struct ScaleInserter<Precision, -1> {
    static void insert(funcMapType&) {}
};

3. 实现遍历所有Precision的插入逻辑

// 递归遍历从CurrentPrecision到1的所有Precision
template<int CurrentPrecision>
struct PrecisionInserter {
    static void insert(funcMapType& func_map) {
        // 插入当前Precision对应的所有Scale
        ScaleInserter<CurrentPrecision, CurrentPrecision>::insert(func_map);
        // 递归处理更小的Precision
        PrecisionInserter<CurrentPrecision - 1>::insert(func_map);
    }
};

// 递归终止条件:当CurrentPrecision < 1时停止
template<>
struct PrecisionInserter<0> {
    static void insert(funcMapType&) {}
};

4. 初始化映射函数

static funcMapType initializeNumericCreatorMap() {
    funcMapType numeric_creators;
    // 遍历Precision从38到1,生成所有合法组合
    PrecisionInserter<38>::insert(numeric_creators);
    return numeric_creators;
}

方案说明

这个实现通过两层递归完全避免了重复组合:

  • 外层递归遍历所有precision值(从38到1)
  • 内层递归对每个precision遍历所有合法的scale值(从precision到0)

每个参数组合只会被处理一次,完全符合需求,且兼容C++17标准。如果需要测试小范围参数(比如precision到3),只需将PrecisionInserter<38>改为PrecisionInserter<3>,会生成预期的无重复组合。

内容的提问来源于stack exchange,提问作者Will Ayd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:13:11