这个宏可以转换为函数吗? [英] Can this macro be converted to a function?

查看:103
本文介绍了这个宏可以转换为函数吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在重构代码和消除我们现在教导的所有那些#defines的时候,我遇到了用来计算结构中的元素数量的美丽:

While refactoring code and ridding myself of all those #defines that we're now taught to hate, I came across this beauty used to calculate the number of elements in a structure:

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

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

Very useful as it is but can it be converted into an inline function or template?

OK,ARRAYSIZE将是一个更好的名称但是这是遗留代码(不知道它来自哪里,至少15岁),因此我按原样粘贴它。

OK, ARRAYSIZE would be a better name but this is legacy code (no idea where it came from, it's at least 15 years old) so I pasted it 'as is'.

推荐答案

如前所述,代码实际上计算了数组中元素的数量,而不是struct。我会在我想要的时候显式地写出sizeof()划分。如果我要使它成为一个函数,我想在它的定义中明确它期望一个数组。

As been stated, the code actually work out the number of elements in an array, not struct. I would just write out the sizeof() division explicitly when I want it. If I were to make it a function, I would want to make it clear in its definition that it's expecting an array.

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

上面类似于 xtofl的,除了它防止传递一个指针到它(说指向一个动态分配的数组)

The above is similar to xtofl's, except it guards against passing a pointer to it (that says point to a dynamically allocated array) and getting the wrong answer by mistake.

EDIT :简化为 JohnMcG
EDIT :inline。

EDIT: Simplified as per JohnMcG. EDIT: inline.

不幸的是,上面的代码不提供编译时的答案(即使编译器内联&优化它是一个常数在引擎盖下),所以不能用作编译时常量表达式。即它不能用作声明静态数组的大小。在C ++ 0x下,如果用 constexpr 替换关键字 inline (constexpr是内联隐式),这个问题就会消失。

Unfortunately, the above does not provide a compile time answer (even if the compiler does inline & optimize it to be a constant under the hood), so cannot be used as a compile time constant expression. i.e. It cannot be used as size to declare a static array. Under C++0x, this problem go away if one replaces the keyword inline by constexpr (constexpr is inline implicitly).

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

jwfearn的解决方案工作对于编译时,但涉及具有有效地保存在新名称的声明中的数组大小的typedef。然后通过经由该新名称初始化常数来计算数组大小。在这种情况下,也可以简单地将数组大小从开始保存为常数。

jwfearn's solution work for compile time, but involve having a typedef which effectively "saved" the array size in the declaration of a new name. The array size is then worked out by initialising a constant via that new name. In such case, one may as well simply save the array size into a constant from the start.

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

Martin York's posted solution also work under compile time, but involve using the non-standard typeof() operator. The work around to that is either wait for C++0x and use decltype (by which time one wouldn't actually need it for this problem as we'll have constexpr). Another alternative is to use Boost.Typeof, in which case we'll end up with

#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

em> foo 是数组的名称。

where foo is the name of an array.

这篇关于这个宏可以转换为函数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆