我们一般在程序中计算数组类型变量的大小通过定义如下的一个宏实现,如NUM_ELEMENTS定义:#defineNUM_ELEMENTS(x)(sizeof((x))/sizeof((x)[0]))
该宏在计算正确的数组类型变量时不存在问题,但应用到指针上或应用到支持[]重载的类时都会有问题。
通过C++实现一种安全高效的数组大小运算符dimensionof(),以下是该运算符的实现:
template<intN>
原理:声明一个模板函数static_array_size_fn(),它接受一个元素类型为T、大小为N的数组的引用,T和N分别作为它的两个模板参数,这样一来,指针以及用户自定义类型就拒之门外了,该函数返回array_size_struct类模板的一个实例,该类模板以static_array_size_fn()接受的数组大小来实参化,且内部包含一个对应大小的字节数组。dimensionof()宏则简单地将sizeof操作符应用到static_array_size_fn返回的实例中的数组成员身上,从而得到数组大小。
structarray_size_struct
{
byte_t c[N];
};
template<classT,intN>
array_size_struct<N>static_array_size_fn(T(&)[N]);
#definedimensionof(x) sizeof(static_array_size_fn(x).c)
该dimensionof()总是在编译期被求值,因此dimensionof()可以被用在常量可以使用的任何地方。
C++标准中,sizeof的操作数不会被求值,所以无需产生static_array_size_fn()函数体,从而该设施是零代价的,没有任何运行期开销,也不会代码膨胀。
测试代码如:
char cArray[40];
如例:对于危险的调用,利用上面的方式,在编译期就可以把异常隔离起来,C++模板元编程的功劳。现在可以方便的把dimensionof运算符应用到你的工程里了。
char *pCArray=cArray;
vector<char>vecChar(50);
size_tc_cArray=NUM_ELEMENTS(cArray);//Ok
size_tc_pCArray=NUM_ELEMENTS(pCArray);//编译通过,执行异常
size_tc_vecChar=NUM_ELEMENTS(vecChar);//编译通过,执行异常
c_cArray=dimensionof(cArray);//Ok
c_pCArray=dimensionof(pCArray);//编译不能通过
c_vecChar=dimensionof(vecChar);//编译不能通过
版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明!