如何知道一个const数组的大小?

18

给定以下代码:

const myStr codesArr[] =  {"AA","BB", "CC"};     

myStr是一个封装了char*的类。 我需要循环遍历数组中的所有项,但我不知道有多少项。 我不想定义一个代表大小(在此情况下为3)的const值。

使用类似以下代码是否安全:

const int size = sizeof(codesArr) / sizeof(myStr);

该怎么办?


2
这个问题是关于C还是C++的?对于C++,我真的建议使用std::array(如果您的编译器不是C++11,则使用std::tr1::array)而不是内置数组。并且很可能使用std::string而不是myStr所做的任何事情。 - Grizzly
1
你可以选择使用 sizeof(codesArr) / sizeof(codesArr[0]);,但需要遵守 Luchian Grigore 提到的限制。 - Some programmer dude
3个回答

37
这样做的安全明确方法是使用 std::extent(自C++11起):
const size_t size = std::extent<decltype(codesArr)>::value;

19

只要你不将其作为参数传递给函数,就可以使用int size = sizeof(codesArr) / sizeof(myStr);,因为数组会衰减为指针并且失去大小信息。

你也可以使用模板技巧:

template<typename T, int sz>
int size(T(&)[sz])
{
    return sz;
}

1
@Maroun85 是的,有一个隐式转换(不是具体的类型转换)。只要大小可以表示为int类型,这个转换就不会造成任何问题。 - nos
1
你的 size() 函数应该在 C++11 中使用 constexpr,或者在 C++03 中使用宏技术,以便它可以用作常量表达式。 - Nawaz
@ecatmur:哦,我不知道那个。无论如何,在这种情况下,宏技术就是方法。 - Nawaz
有没有任何特别的原因不使用 size_t - Jens Gustedt
@JensGustedt 不,我认为 size_t 更合适。 - Luchian Grigore
显示剩余2条评论

1

在 C++11 之前获取数组大小的最佳方式可以在this link找到。这是一个复杂的模板技巧,但与其他方法相比具有许多优势,如上面链接中所讨论的。该方法是使用以下宏+函数:

template <typename T, size_t N>
char ( &_ArraySizeHelper( T (&array)[N] ))[N];

#define countof( array ) (sizeof( _ArraySizeHelper( array ) ))

它的优点之一是,它完全是一个编译时操作,这比在运行时执行要好。在C++11之前,它是唯一允许您将操作结果用作另一个数组大小的方法(因为它是一个编译时常量)。

它有什么那么复杂的?这是一个直接使用模板参数推断的方法。(如果你想看一些复杂的模板技巧,可以看看一些Boost源代码。) - James Kanze
3
当然,你的代码存在未定义行为的事实,因为它包含一个以下划线开头并后跟大写字母的符号。 - James Kanze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接