【问题标题】:calculate number of elements from a fixed array (similar to sizeof)从固定数组中计算元素的数量(类似于 sizeof)
【发布时间】:2014-03-25 17:12:41
【问题描述】:

我正在用 C++ 开发一个库,以便帮助开发人员完成某些任务。 通常,为了以动态方式(不使用#define SIZE 或静态 int SIZE)计算整数数组的大小(例如),我会使用 sizeof(v) / sizeof(int)。我正在尝试编写一段可以自动为我做这些事情的代码,我决定调用 if lengthof。 代码在这里:

template <class T> int _typesize(T*) { return sizeof(T); }
#define lengthof(x) (sizeof(x) / _typesize(&x))

我使用模板获取数组的类型,然后以字节为单位返回其大小。在 GCC 中,我知道可以使用 typeof,因此我可以将 _typesize(&x) 替换为 sizeof(typeof(x)),但在 MSVC 上是不可能的。 _typesize 是一种兼容的方式,但我认为它可能很昂贵,因为它将指针作为副本传递。有一种优雅的方法可以做到这一点?

【问题讨论】:

  • std::vectorstd::array
  • 使用来自stackoverflow.com/a/14713274/459640ArraySizeHelper函数和arraysize
  • 通过副本传递指针几乎没有昂贵的操作...
  • 对于不使用太多内存的局部变量,我通常使用 C 样式的数组(由于堆栈与堆等)

标签: c++ arrays sizeof typeof


【解决方案1】:

此任务不需要宏。如果你有一个符合要求的编译器

template<class T, size_t len>
constexpr size_t lengthof(T(&)[len]) {return len;}
//the parameter is an unnamed reference to a `T[len]`, 
//where `T` is deduced as the element type of the array
//and len is deduced as the length of the array.
//similar to `T(*)[len]` in C, except you can pass the array
//directly, instead of passing a pointer to it.
//added benefit that if you pass a `T*` to it, it produces a compiler error.

或者,如果您使用的 Visual Studio 尚不符合标准...

template<class T, size_t len>
std::integral_constant<size_t, len> lengthof(T(&)[len]) {return {};}
//VC++ doesn't have constexpr, so we have to use `std::integral_constant` instead :(
//but how it works is 100% identical

如果您想要更便携的方式,宏仍然是最好的:

#define lengthof(arr) sizeof(arr) / sizeof(arr[0])
//doesn't respect namespaces, evaluates arguments multiple times
//and if you pass a `T*` to it, it evaluates to `1` depending on context.

但重申我的评论,我会考虑所有这些糟糕的代码。使用std::vectorstd::array

【讨论】:

  • 你能给一个现在在 C++ 上的 C 程序员解释一下 T(&amp;)[len] 是什么意思吗?
  • @TheMask:对长度为 len 和元素类型为 T 的数组的引用。类似的指针类型,T(*)[len],与 C 中的相同。
  • @MikeSeymour:谢谢。这个template 中的len 参数从何而来?这是某种类型的重载吗?
  • @TheMask:如果您有char array[3],那么array 的类型为char[3]。当你调用lengthof(array)时,C++编译器知道参数是char(&amp;)[3],所以推断T一定是charlen一定是3。然后函数返回len,即3。对于此示例,它 100% 等效于 constexpr size_t lengthof( char(&amp;)[3]) {return 3;}constexpr 表示它在编译时执行(ish),因此根本没有运行时开销。
  • 我喜欢 T(&)[n] 解决方案,谢谢!哦,老实说,我忘了我也可以使用 sizeof(v[0]) :P 这对于 ANSI C 代码来说是一个很好的解决方案。
【解决方案2】:

通常,您会使用:sizeof(x) / sizeof(x[0]),它不依赖任何扩展。

【讨论】:

    【解决方案3】:

    获取数组长度的标准 C++ 方法是 sizeof(arr) / sizeof(arr[0])。您是否想通过将其打包到宏中来隐藏它完全是另一回事。

    附带说明,如果您的 _typesize 位于全局命名空间中,则该名称保留用于实现并且非法使用。在命名空间中它在技术上是合法的,但一般来说,您可以通过完全避免前导下划线来避免保留名称问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-18
      • 2020-02-19
      • 2023-03-21
      • 2012-02-21
      • 1970-01-01
      • 2020-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多