C++标准库编译期通用获取std::array/span/C数组大小方法查询
问题背景
我在C++标准库中检索许久,始终未找到可在编译期计算std::array、std::span及C原生数组类型元素个数的模板工具,期望找到类似下文示例中get_element_count的标准实现。
我并非寻求自定义实现方案——示例中的get_element_count已可正常工作,只是我原本认为标准库已提供对应实现。
该工具需要像std::tuple_size一样以类型作为模板参数,且适配范围更通用。
核心结论:C++标准库中不存在该通用工具,你检索不到的原因就是标准库根本没有提供这一统一接口。
目前标准库的编译期长度获取能力是分散在不同工具中的:
- C原生数组的编译期长度可通过
<type_traits>头文件的std::extent_v<T>获取- 固定长度的
std::array、固定extent的std::span的编译期长度可通过<utility>头文件的std::tuple_size_v<T>获取
三类类型没有统一的适配接口,动态extent的std::span因为长度运行时可变,本身也不存在编译期常量长度。
通用适配效果演示(自定义实现,非标准库)
以下是可同时适配三类类型的get_element_count实现及测试用例:
#include <iostream> #include <array> #include <span> #include <type_traits> template<typename> inline constexpr size_t get_element_count = 0; template<typename T, size_t N> inline constexpr size_t get_element_count<std::array<T, N>> = N; template<typename T, size_t N> inline constexpr size_t get_element_count<std::span<T, N>> = N; template<typename T, size_t N> inline constexpr size_t get_element_count<T[N]> = N; int main () { std::array<char, 7> a = {'0','1','2','3','4','5','6'}; std::span b = a; // 动态extent的span,无编译期固定长度 std::span<char, 7> c = a; // 固定extent的span char d[7] = {'0','1','2','3','4','5','6'}; long e[7] = { 0L, 1L, 2L, 3L, 4L, 5L, 6L}; std::cout << get_element_count<decltype(a)> << std::endl; // 输出7 std::cout << get_element_count<decltype(b)> << std::endl; // 输出0 std::cout << get_element_count<decltype(c)> << std::endl; // 输出7 std::cout << get_element_count<decltype(d)> << std::endl; // 输出7 std::cout << get_element_count<decltype(e)> << std::endl; // 输出7 }
典型使用场景
这类编译期常量多用于泛型编程场景,可统一适配不同的固定长度连续容器类型,示例如下:
template <typename T, size_t N> struct S {T t; size_t n = N;}; using A = std::array<int, 5>; using B = std::span<int, 5>; template <typename T> using C = S<typename T::value_type, 2 * get_element_count<T>>; using D_double = C<A>; using E_double = C<B>;
内容的提问来源于stack exchange,提问作者Patrick Fromberg
相关产品推荐
相关产品推荐

