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

C++中将std::array作为模板参数时能否省略冗余的长度参数N?

解决方案

C++20 最优方案(使用auto非类型模板参数)

C++20引入了auto作为非类型模板参数的语法,允许编译器自动推导非类型参数的类型,你可以完全省略显式的N声明,在类内部自动推导数组长度:

#include <array>
#include <concepts>

// 可选:添加约束确保传入的非类型参数是std::size_t类型的std::array
template<typename Arr>
concept SizeArray = std::same_as<Arr, std::array<std::size_t, std::tuple_size_v<Arr>>>;

template<typename T, SizeArray auto A>
class Foo {
    // 类内部可直接推导出N
    static constexpr std::size_t N = std::tuple_size_v<decltype(A)>;
    // 你的其他实现
};

你可以用std::array的CTAD(类模板实参推导)简化实例化,写法非常接近你要的效果:

Foo<int, std::array{5, 3, 4}> baz;

如果觉得写std::array还是麻烦,可以加一个极简的辅助变量模板:

template<std::size_t... Is>
constexpr std::array<std::size_t, sizeof...(Is)> arr = {Is...};

// 实例化写法就会更简洁
Foo<int, arr<5,3,4>> baz;

说明:你期望的Foo<int, {5,3,4}>写法当前无法实现,因为花括号初始化列表本身不具备类型,无法参与auto非类型参数的推导,这是C++标准的现有约束。


为什么你之前的模板模板参数写法不生效

模板模板参数的作用是接收模板本身作为参数,而你需要的是std::array的实例对象作为非类型参数,二者是完全不同的语法用途,因此你的尝试方向是错误的。


C++17兼容方案

如果你还在使用C17(C17开始支持std::array作为非类型模板参数),可以搭配辅助变量模板实现类似效果:

#include <array>

template<typename T, std::size_t N, std::array<std::size_t, N> A>
class Foo {
    // 你的实现
};

// 辅助变量模板
template<std::size_t... Is>
constexpr std::array<std::size_t, sizeof...(Is)> arr = {Is...};

// 实例化写法
Foo<int, 3, arr<5,3,4>> bar;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 12:15:00