当std::array用作非类型模板参数时能否自动推导大小?能否省略SIZE模板参数?
好问题!咱们逐个来拆解你的疑问:
问题1:当std::array用作非类型模板参数时,能否自动推导其大小?
在C17及之后的标准里,完全可以!编译器能够自动推导出std::array的大小模板参数SIZE,前提是你用对了语法——借助C17引入的自动推导非类型模板参数特性。
举个简单的例子:
#include <array> #include <iostream> template <auto& Arr> struct SizePrinter { void print() { // 直接通过Arr.size()获取大小,不需要手动传SIZE std::cout << "Array size: " << Arr.size() << '\n'; } }; // 全局的std::array,满足静态存储期要求 std::array<int, 5> my_global_arr{}; int main() { SizePrinter<my_global_arr> printer; printer.print(); // 输出:Array size: 5 return 0; }
这里用auto&作为非类型模板参数,编译器会自动推导Arr的完整类型(包括std::array的元素类型和大小),完全不需要你手动指定SIZE。
问题2:能否省略SIZE模板参数,从array实参推导出来?
当然可以!甚至连T参数都能一起省略。针对你给出的原代码,咱们可以直接改造得更简洁:
方案1:最简写法(直接推导完整array类型)
如果你不需要在类里显式用到T或SIZE,直接用auto&就能搞定:
template <auto& ARR> class Foo {}; std::array<std::string, 3> str_arr; Foo<str_arr> foo; // 编译器自动推导ARR是std::array<std::string,3>&,无需指定T和SIZE
方案2:需要用到T或SIZE的场景
如果你需要在类内部使用元素类型T或者大小SIZE,可以通过decltype从传入的ARR中提取:
template <auto& ARR> class Foo { public: // 提取元素类型 using ElementType = typename decltype(ARR)::value_type; // 提取数组大小,编译期常量 static constexpr size_t ArraySize = decltype(ARR)::size(); void show_details() { std::cout << "Element type: " << typeid(ElementType).name() << ", Array size: " << ArraySize << '\n'; } }; std::array<double, 4> num_arr; Foo<num_arr> foo; foo.show_details(); // 输出类似:Element type: double, Array size: 4
额外注意点
- 这个特性只支持C17及以上版本,如果你还在使用C11/C++14,那没办法省略
SIZE和T,必须显式声明并指定。 - 作为非类型模板参数的
std::array必须是静态存储期的对象(比如全局变量、static局部变量、static成员变量),栈上的普通局部变量无法作为实参传递,会触发编译错误。
内容的提问来源于stack exchange,提问作者user2141130
相关产品推荐
相关产品推荐

