为什么 std::bitset 以小端方式公开位?

Why does std::bitset expose bits in little-endian fashion?

当我使用 std::bitset<N>::bitset( unsigned long long ) 时,它构造了一个位集,当我通过 operator[] 访问它时,这些位似乎以小端方式排序。示例:

std::bitset<4> b(3ULL);
std::cout << b[0] << b[1] << b[2] << b[3];

打印 1100 而不是 0011 即结尾(或 LSB)位于小(低)地址,索引 0.

查找标准,它说

initializing the first M bit positions to the corresponding bit values in val

程序员自然会想到从LSB到MSB(从右到左)的二进制数字。所以 前 M 位位置 可以理解为 LSB → MSB,因此位 0 将位于 b[0].

然而,在移动下,定义变为

The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled.

这里必须将 E1 中的位解释为从 MSB → LSB 然后左移 E2 次。如果它是从 LSB → MSB 写的,那么只右移 E2 次就会得到相同的结果。

令我惊讶的是,在 C++ 的其他任何地方,该语言似乎都采用自然的(英语;从左到右)书写顺序(在进行移位等按位运算时)。为什么这里不一样?

就标准而言,没有字节顺序的概念。当涉及到std::bitset时,[template.bitset]/3定义位位置:

When converting between an object of class bitset<N> and a value of some integral type, bit position pos corresponds to the bit value 1<<pos. The integral value corresponding to two or more bits is the sum of their bit values.

在您的标准报价中使用位位置的定义

initializing the first M bit positions to the corresponding bit values in val

a val 与二进制表示 11 导致 bitset<N> bb[0] = 1b[1] = 1 和其余位设置为 0

这与通常的位编号方式一致——位 0 表示 20,位 1 表示 21,等等。它与体系结构的字节顺序无关,后者涉及字节顺序而不是位顺序。