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

C++20中如何推导ArrayND类的维度模板参数?

N维数组类模板参数推导问题

问题描述

我实现了一个带两个模板参数(类型T和维度数N)的N维数组类ArrayND。希望构造3维数组时直接写ArrayND<float> A(x, y, z);,而不用冗余指定维度数3(即避免ArrayND<float, 3> A(x, y, z);这种写法)。

我尝试编写了以下推导指南:

template <class T, class ...I>
ArrayND(I...) -> ArrayND<T, sizeof...(I)>;

但用G++12.1.0加-std=c++20编译时,报错“error: wrong number of template arguments (1, should be 2)”。想问这个需求是否可行?如果可行,我的代码哪里错了?

类的简化实现如下:

template <class T, size_t N>
class ArrayND {
    // 存储和维度信息
    std::vector<T> storage;
    size_t dims[N];

public:
    // 构造函数:接收N个维度参数
    template <class ...I> requires (sizeof...(I) == N && std::is_integral_v<std::common_type_t<I...>>)
    constexpr ArrayND(const I ...i): storage((i * ...)), dims{i...} {}

private:
    // 索引转换:将多维索引转为一维存储的索引
    template <decltype(N) M=N-1, class I, class ...J>
    constexpr const auto flattened_index(const I i, const J ...j) const {
        auto index = i * std::accumulate(dims+N-M, dims+N, 1, std::multiplies());
        if constexpr (sizeof...(J) > 0) index += flattened_index<M-1>(j...);
        return index;
    }

public:
    // 多维索引访问
    template <class ...I> requires (sizeof...(I) == N && std::is_integral_v<std::common_type_t<I...>>)
    constexpr auto &operator()(const I ...i) { return storage[flattened_index(i...)]; }

    // 获取底层数据指针
    constexpr auto data() { return storage.data(); }
};

解决方案

这个需求完全可行,问题出在推导指南的写法没有匹配部分模板参数指定的场景:

  1. 原推导指南的问题
    你写的推导指南是针对完全不指定模板参数的情况(比如ArrayND(x,y,z)),但你需要的是用户显式指定T、推导N的场景(ArrayND<float>(x,y,z))。原推导指南无法关联用户已经指定的T,导致编译器无法识别需要推导的是第二个模板参数N,从而报参数数量错误。

  2. 正确的推导指南写法
    要支持部分指定模板参数的推导,推导指南的左侧需要明确匹配“指定了T,传入构造参数”的形式:

    template <class T, class... I>
    ArrayND<T>(I...) -> ArrayND<T, sizeof...(I)>;
    

    这样当你写ArrayND<float> A(x,y,z);时,编译器会匹配这个推导指南:T被显式指定为float,sizeof...(I)是3(对应3个构造参数),因此推导出完整的模板类型ArrayND<float, 3>,完美符合需求。

  3. 验证说明
    修改推导指南后,用G++12.1.0加-std=c++20编译即可正常通过,构造函数的requires约束也会自动满足(推导的N等于构造参数的数量)。

内容的提问来源于stack exchange,提问作者Michael Greenburg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:25:34