如何在编译时获取数组大小?
Posted
技术标签:
【中文标题】如何在编译时获取数组大小?【英文标题】:How to get an array size at compile time? 【发布时间】:2018-03-23 16:11:36 【问题描述】:在定义 C 样式数组或 C++11 数组时,通常需要获取一个编译时常量来表示此类数组的大小。在 C 中,使用宏来做这样的事情而不依赖于可变长度数组(因为它在 C99 中不是标准的):
#define ARRAY_SIZE 1024
int some_array[ARRAY_SIZE];
或
#define countof(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0]))
在 C++ 中,是否可以定义更惯用的东西?
【问题讨论】:
为什么不直接使用std::array<int, ARRAY_SIZE>
? std::array::size
已经是 constexpr
@CoryKramer 它不适用于 C 样式数组,仅此而已。见下文如何定义一个constexpr countof
,它接受 C 风格的数组、C++11 数组和元组。
你可以迁移到std::vector
:std::vector<int> some_array(ARRAY_SIZE);
。然后使用some_array.size()
。
@ThomasMatthews std::vector
是 std::vector
,std::array
和 C 风格的数组是别的东西。
std::vector
的一个优点是您不需要将容量传递给函数。使用数组,您将传递数组的起始地址和容量。是的,我知道其中的区别。
【参考方案1】:
使用 C++ 的 constexpr
,可以找到数组的编译时常量大小:
template<std::size_t N, class T>
constexpr std::size_t countof(T(&)[N]) return N;
并按如下方式使用:
int some_array[1024];
static_assert(countof(some_array) == 1024, "wrong size");
struct another_array[1];
static_assert(countof(another_array) == 1, "wrong size");
请参阅full program demo on coliru。
如果有人喜欢交替使用std::array
和C 风格的数组,可以使用SFINAE 添加countof
的定义,采用std::array
s 和std::tuple
s:
template<class Array, std::size_t N = std::tuple_size<Array>::value>
constexpr std::size_t countof(Array&) return N;
请参阅enriched program demo on coliru。
【讨论】:
【参考方案2】:如果您的标准库与 C++17 兼容,只需使用 std::size(xyz)
。
如果您的标准库尚未提供该功能,您可以轻松实现自己,the constexpr
-specifier is C++11。
【讨论】:
很有趣,std::size
现在是constexpr
。这对现代 C++ 中经典 sizeof
运算符的使用有何影响?什么时候选择一个而不是另一个?【参考方案3】:
如果您不想引入自己的函数并且只使用 STL 来实现,那么可以使用 std::distance
检索大小:
#include <utility>
auto size = std::distance(std::begin(some_array), std::end(some_array));
自 C++17 起为constexpr
【讨论】:
这里是初学者,看来你不需要c++17,直接做constexpr size_t size = std::end(some_array) - std::begin(some_array);
你好@MarkusvonBroady,你的 C++14 解决方法很棒。如果你有 C++17,使用 std::distance
而不是运算符 -
会更好,因为它适用于更多的容器(例如 std::list
)。作为更通用的解决方案,我建议using std::begin, std::end
并调用begin(some_array)
和end(some_array)
。这将允许某人将它与用户定义的容器一起使用。以上是关于如何在编译时获取数组大小?的主要内容,如果未能解决你的问题,请参考以下文章
TypeScript:如何在编译时声明固定大小的数组以进行类型检查