std::is_bounded_array是编译期类型判断工具,仅对t[n]返回true,需配合decltype使用,对指针、std::array等均返回false,且必须在constexpr或模板上下文中使用。

std::is_bounded_array 是个编译期判断工具,不是运行时函数
它只能在模板元编程或 constexpr 上下文中起作用,不能像普通函数那样传入变量调用。你写 std::is_bounded_array<decltype>::value</decltype> 是对的,但写 std::is_bounded_array<arr></arr> 或 std::is_bounded_array<int></int>(漏掉 decltype 或类型包)就会编译失败。
- 必须用
decltype获取数组的完整类型(含维度),例如int[3]、char[10] - 裸写
int[5]作为模板参数合法,但实际中几乎总是从变量推导,所以decltype更安全 - 它对指针、
std::array、std::vector全部返回false—— 只认 C 风格定长数组类型
常见误判:把指针或退化数组当定长数组
函数参数里写 void f(int arr[5]),实际形参类型是 int*,decltype(arr) 是指针,std::is_bounded_array 必然为 false。C++ 不允许函数参数以数组类型传递(会自动退化)。
- 检查数组长度?得靠模板推导:
template<size_t n> void f(int (&arr)[N]) { static_assert(std::is_bounded_array<decltype>::value); }</decltype></size_t> - 用
std::is_pointer_v<decltype></decltype>对比确认是否已退化 - VS 和 GCC 对
int a[5]的decltype(a)一致,但 Clang 在某些模板上下文中可能更严格,建议统一用std::is_bounded_array_v<decltype></decltype>(C++17 起支持 _v 后缀)
和 std::is_unbounded_array 的区别与配合使用
std::is_unbounded_array 判断的是 T[] 这种不带长度的声明(极少用,仅在声明外部数组或某些 ABI 场景出现),而 std::is_bounded_array 判断 T[N]。两者互斥,且都为 false 时大概率是其他类型。
- 典型场景:写类型擦除容器时,想区分「定长数组」和「动态分配内存」,需同时排除
std::is_pointer、std::is_array(它对两者都为true) -
std::is_array_v<t></t>是父集判断,std::is_bounded_array_v<t></t>是其子集;别用错层级 - 注意:
std::is_bounded_array_v<int></int>是false,std::is_unbounded_array_v<int></int>才是true
constexpr 场景下怎么安全用
在 if constexpr 中做分支是最常见用途,但要注意模板参数必须能被常量表达式求值。比如局部变量数组可以,但函数参数若未以引用方式传入就不行。
立即学习“C++免费学习笔记(深入)”;
- 正确:
template<typename t> constexpr auto get_size() { if constexpr (std::is_bounded_array_v<t>) return std::extent_v<t>; else return size_t{0}; }</t></t></typename> - 错误:
void g(int x[5]) { if constexpr (std::is_bounded_array_v<decltype>) ... }</decltype>——x是指针,decltype(x)不是数组类型 -
std::extent_v<t></t>和std::rank_v<t></t>必须搭配std::is_bounded_array_v<t></t>使用,否则对非数组类型行为未定义
decltype 输出和 std::is_array 的结果比反复试更容易定位。










