C++实现数组大小运算符dimensionof()

我们一般在程序中计算数组类型变量的大小通过定义如下的一个宏实现,如NUM_ELEMENTS定义:#define NUM_ELEMENTS(x) (sizeof((x))/sizeof((x)[0]))

该宏在计算正确的数组类型变量时不存在问题,但应用到指针上或应用到支持[]重载的类时都会有问题。

通过C++实现一种安全高效的数组大小运算符dimensionof(),以下是该运算符的实现:

template <int N>

struct array_size_struct

{

  byte_t  c[N];

};

 

template <class T, int N>

array_size_struct<N> static_array_size_fn(T (&)[N]);

 

#define dimensionof(x)     sizeof(static_array_size_fn(x).c)

原理:声明一个模板函数static_array_size_fn(),它接受一个元素类型为T、大小为N的数组的引用,TN分别作为它的两个模板参数,这样一来,指针以及用户自定义类型就拒之门外了,该函数返回array_size_struct类模板的一个实例,该类模板以static_array_size_fn()接受的数组大小来实参化,且内部包含一个对应大小的字节数组。dimensionof()宏则简单地将sizeof操作符应用到static_array_size_fn返回的实例中的数组成员身上,从而得到数组大小。

dimensionof()总是在编译期被求值,因此dimensionof()可以被用在常量可以使用的任何地方。

C++标准中,sizeof的操作数不会被求值,所以无需产生static_array_size_fn()函数体,从而该设施是零代价的,没有任何运行期开销,也不会代码膨胀。

测试代码如:

char  cArray[40];

char  *pCArray = cArray;

vector<char> vecChar(50);

 

size_t c_cArray = NUM_ELEMENTS(cArray); // Ok

size_t c_pCArray = NUM_ELEMENTS(pCArray); // 编译通过,执行异常

size_t c_vecChar = NUM_ELEMENTS(vecChar); // 编译通过,执行异常

 

c_cArray = dimensionof(cArray); // Ok

c_pCArray = dimensionof(pCArray); // 编译不能通过

c_vecChar = dimensionof(vecChar); // 编译不能通过

如例:对于危险的调用,利用上面的方式,在编译期就可以把异常隔离起来,C++模板元编程的功劳。现在可以方便的把dimensionof运算符应用到你的工程里了。

 

注:参考《Imperfect C++》。

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值