其他分享
首页 > 其他分享> > c – 可以将此宏转换为函数吗?

c – 可以将此宏转换为函数吗?

作者:互联网

在重构代码并摆脱我们现在被教导讨厌的所有#defines时,我偶然发现了这个用于计算结构中元素数量的美:

#define STRUCTSIZE(s) (sizeof(s) / sizeof(*s))

非常有用,但是它可以转换为内联函数或模板吗?

好的,ARRAYSIZE会是一个更好的名字,但这是遗留代码(不知道它来自哪里,至少15年)所以我按原样粘贴它.

解决方法:

如上所述,代码实际上计算出数组中元素的数量,而不是结构.我会在需要时明确写出sizeof()除法.如果我要使它成为一个函数,我想在其定义中明确表示它期望一个数组.

template<typename T,int SIZE>
inline size_t array_size(const T (&array)[SIZE])
{
    return SIZE;
}

以上类似于xtofl’s,除了它防止传递指针(指向动态分配的数组)并错误地得到错误的答案.

编辑:根据JohnMcG简化.
编辑:内联.

遗憾的是,上面没有提供编译时答案(即使编译器内联并优化它是一个常量),因此不能用作编译时常量表达式.即它不能用作声明静态数组的大小.在C 0x下,如果用constexpr替换关键字inline(constexpr隐式内联),这个问题就会消失.

constexpr size_t array_size(const T (&array)[SIZE])

jwfearn’s解决方案适用于编译时,但涉及有一个typedef,它有效地“保存”了新名称声明中的数组大小.然后通过使用新名称初始化常量来计算数组大小.在这种情况下,也可以简单地从一开始就将数组大小保存为常量.

Martin York’s发布的解决方案也在编译时工作,但涉及使用非标准的typeof()运算符.解决这个问题的方法是等待C 0x并使用decltype(此时我们实际上不需要它来解决这个问题,因为我们将有constexpr).另一种选择是使用Boost.Typeof,在这种情况下我们最终将使用

#include <boost/typeof/typeof.hpp>

template<typename T>
struct ArraySize
{
    private:    static T x;
    public:     enum { size = sizeof(T)/sizeof(*x)};
};
template<typename T>
struct ArraySize<T*> {};

并通过写作使用

ArraySize<BOOST_TYPEOF(foo)>::size

其中foo是数组的名称.

标签:c,macros,c-preprocessor
来源: https://codeday.me/bug/20190926/1822116.html