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
相关产品推荐
相关产品推荐

