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 的数组的引用, T N 分别作为它的两个模板参数,这样一来,指针以及用户自定义类型就拒之门外了,该函数返回 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++ 》。
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值