(注:_M_do_count是bitset的base class _Base_bitset的实现,在bitset的count中直接调用了该函数)
最开始我以为该函数会针对每个字节使用移位来累计bit位的个数,直到我看到下面红色的代码的部分:
-
size_t _M_do_count() const {
-
size_t __result = 0;
-
const unsigned char* __byte_ptr = (const unsigned char*)_M_w;
-
const unsigned char* __end_ptr = (const unsigned char*)(_M_w+_Nw);
-
while ( __byte_ptr < __end_ptr ) {
-
__result += _Bit_count<true>::_S_bit_count[*__byte_ptr];
-
__byte_ptr++;
-
}
-
return __result;
- }
-
// structure to aid in counting bits
-
template<bool __dummy>
-
struct _Bit_count {
-
static unsigned char _S_bit_count[256];
- };
-
template<bool __dummy>
-
unsigned char _Bit_count<__dummy>::_S_bit_count[] = {
-
0, /* 0 */ 1, /* 1 */ 1, /* 2 */ 2, /* 3 */ 1, /* 4 */
-
...
- };
但是,为什么使用这样繁琐的方式来使用呢?
1)如果直接定义为全局变量:
-
unsigned char _S_bit_count[] = {
-
0, /* 0 */ 1, /* 1 */ 1, /* 2 */ 2, /* 3 */ 1, /* 4 */
- };
2)如果定义为静态全局变量:
-
static unsigned char _S_bit_count[] = {
-
0, /* 0 */ 1, /* 1 */ 1, /* 2 */ 2, /* 3 */ 1, /* 4 */
- };
3)如果定义为类的静态成员:
-
struct _Bit_count {
-
static unsigned char _S_bit_count[256];
-
};
-
-
unsigned char _Bit_count::_S_bit_count[] = {
-
0, /* 0 */ 1, /* 1 */ 1, /* 2 */ 2, /* 3 */ 1, /* 4 */
- };
以上。
若不使用bitset的count成员函数,编译器不会生成_Bit_count
根据进一步的测试发现:即使产生了模板类的一个实例,若代码中没有访问该类的静态成员,静态成员并不会初始化。这不知是语言的标准行为还是编译器优化的结果。
测试代码:
-
#include <iostream>
-
-
using namespace std;
-
-
class object {
-
public:
-
object(void) { cout << "object() at " << this << endl; }
-
};
-
-
template <int dumb>
-
class dummy {
-
public:
-
dummy(void) { cout << "dummy() at " << this << endl; }
-
-
static object obj;
-
};
-
-
template <int n>
-
object dummy<n>::obj;
-
-
int main(int argc, char **argv)
-
{
-
cout << "begin" << endl;
-
-
dummy<0> a;
-
-
// 即使已经产生了dummy<0>的定义,若没有访问dummy<0>::obj的代码,dummy<0>::obj依然不会初始化。
-
// object *p = &a.obj;
-
-
return 0;
- }