Interesting. 如何获取一个数组长度

Stupid C++ Tricks: A better sizeof_array()

先上代码:

template<typename Ty, size_t Num>
char(&CountOfRequireArrayArgumentT(const Ty(&)[Num]))[Num];

#define BX_COUNTOF(_x) sizeof(bx::CountOfRequireArrayArgumentT(_x) )

-------------------------------------------------------------------------------------------------------------------------

一种简单的写法是:(there is always a well-known solution to every human problem — neat, plausible, and wrong

#define sizeof_array(x) (sizeof(x) / sizeof(x[0])) 

但因为这是宏,没有任何类型检查,只要展开后语句合法。

#define BAD_SIZEOF_ARRAY(x) (sizeof(x) / sizeof(x[0]))  
  
int main()  
{  
    int ia[10];  
    std::vector< double > dv;  
    std::string s;  
    float* fp;  
  
    std::printf("BAD_SIZEOF_ARRAY(ia): %d\n", BAD_SIZEOF_ARRAY(ia));  
    std::printf("BAD_SIZEOF_ARRAY(dv): %d\n", BAD_SIZEOF_ARRAY(dv));  
    std::printf("BAD_SIZEOF_ARRAY(s): %d\n", BAD_SIZEOF_ARRAY(s));  
    std::printf("BAD_SIZEOF_ARRAY(fp): %d\n", BAD_SIZEOF_ARRAY(fp));  
}  

C++里面Macro functions没有强类型检查,而是允许 duck typing(哈哈 interesting)。 

----------------------------------------------------------------------------------------------

为了保证只允许静态数组使用,于是有了上面第一种写法。下面解释一下

1. template< typename T, size_t N > void OnlyTakesArray(T (&)[N]);

一个模板函数签名,接收一个类型为T,长度为N的静态数组引用为参数。没毛病。

1.5:如果你要写成这样:直接返回N,可能就有问题了:

template< typename T, size_t N > size_t sizeof_array(T (&)[N])  
{  
    return N;  
} 

一些老的编译器(或者没有inline优化,或者不能通过类似c++11 constexpr等方式告诉编译器这是个编译期常量)会生成一个运行时函数,也就是说编译期不能使用这个N

2. “sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1”

那么 sizeof(char[N]) 就是N了,所以我们要想办法搞个char[N]出来,于是:

template< typename T, size_t N > char (&sizeof_array(T (&)[N]))[N]; 

char(&xxx())[N] 的意思是,xxx()这个函数会返回一个char[N]的引用。==!

3. “ The sizeof operator yields the number of bytes in the object representation of its operand. The operand is either an expression, which is not evaluated, or a parenthesized type-id.”

意思是我们不需要实现sizeof_array这个函数。good.

  

猜你喜欢

转载自www.cnblogs.com/redips-l/p/12195821.html
今日推荐