【发布时间】:2020-02-25 07:31:55
【问题描述】:
有没有提到在 C++20 以后的 C++ 未来版本中或在标准库中具有特定的 bitstream 对象?例如;我们可以有一个std::bitset<n> 对象,其中n 是一个已知的常量整数值。
伪例子:
#include <bitstream>
template<unsigned N>
class Foo {
public:
std::bitset<N> bits_;
};
这里我们有一个类模板,它将指定std::bitset 对象中有多少位。这很好。
我们还有stream 对象,例如iostream、fstream、sstream 等,我们可以将各种数据类型的值馈送到这些流中,读取或写入字符串流、文件流,到控制台或终端的 I/O 流等...
我想知道的是,是否有任何建议使用类似上面的流对象,但特定于类似于std::bitset 的性质的任意位序列,您可以将一组位输入流.例如,它可能看起来像这样:
#include <bitset>
#include <bitstream> // not an actual library - only suggestive
int main() {
std::bitset<8> byte{0xFE};
std::bitset<16> word{0xFEDC};
std::bitset<32> dword{0xFEDCBA98};
std::bitset<64> qword{0xFEDCBA9876543210};
std::bitstream bs;
bs << byte << word << dword << qword;
std::cout << bs;
return 0;
}
这里的预期输出是:
11111110111111101101110011111110110111001011101010011000111111101101110010111010100110000111011001010100001100100001000
取决于预期用途的字节序符号...
逆转也适用。如果我们有一个已经填充的bitstream 对象,就像上面示例中的对象一样,我们可以从bitstream 中提取特定的位序列,如下所示:
#include <bitset>
#include <bitstream> // not an actual library - only suggestive
#include <iomanip> // manipulators for bitstreams not yet implemented...
int main() {
std::bitset<8> byte{0xFE};
std::bitset<16> word{0xFEDC};
std::bitset<32> dword{0xFEDCBA98};
std::bitset<64> qword{0xFEDCBA9876543210};
std::bitstream bs;
bs << byte << word << dword << qword;
std::bitset<3> odd3;
std::bitset<5> odd5;
std::bitset<7> odd7;
bs >> bs::msb >> odd3 >> odd7 >> odd5;
std::cout << odd3 << '\n' << odd7 << '\n' << odd5;
bs >> bs::lsb >> odd5 << odd3 << odd7;
std::cout << odd5 << '\n' << odd3 << '\n' << odd7;
// Or by using a constructor with a value for the bit size...
std::bitset<9> odd9( bs ); // odd9(bs::msb), odd9(bs::lsb)...
return 0;
}
并且预期结果将分别从 MSB 或 LSB 方向拉取位,其大小为 bitset 对象的大小。
就像iostream 和其他流库一样,通过使用<iomanip> 库,我们可以使用格式修饰符将输入或输出分解为任何指定长度的离散bit-segments,例如每4 位或8 位,或者将其显示为十六进制等...所有位操作和计算仍将由std::bitset 负责。
能够将任意的bitset 对象推入或取出bitstream 对象,该对象将与所有其他stream 类似对象兼容,这可能是一个非常强大且有用的工具或功能。
有没有提到类似的东西,或者是否已经存在类似于这种性质的东西,而不必在字符串或其他类型之间来回转换等?
EDIT -User- walnut 在他的回答中给出了一些很好的例子,并且已经可以使用现有的 iostream 对象和运算符来完成。您可以阅读他的回答和讨论中的 cmets,但是,我只是想说明我对 stream 对象库的推理,该对象库的编写和设计目的是明确且专门用于 bitset 数据类型。
想象一个这样的函数:
// Not written with perfect syntax or compilation in mind,
// only psuedo to illustrate a point.
template<typename... T>
std::ostream& concatinateBitSequences( T&& ... t ) { // assuming all t are bitset<n>
std::stringstream sstream;
sstream << t...;
return sstream;
}
然后比较一下……
// Not written with perfect syntax or compilation in mind,
// only psuedo to illustrate a point.
template<typename... T>
std::bitstream& concatinateBitSequences( T&& ... t ) { // assuming all t are bitset<n>
std::bitstream bs;
bs << t...;
return bs;
}
调用者,用户将知道它正在显式返回bitstream,或者与任意stream对象进行比较!这是我的主要意图或目标......它更倾向于可读性,并且在代码中更具表现力,显示出正确的意图。此外,它将与bitset 对象紧密耦合,这意味着bitstream 对象将只接受来自bitsets 或其他bitstream 对象的数据,但它可以将其数据传递给bitsets,@ 987654357@s 或其他 stream 对象。
【问题讨论】:
-
如果你有这方面的用例,那么一定要继续写它(虽然看起来非常极端,我们似乎正在远离流)。我个人会使用
std::vector<bool>并创建一个bitset_iterator并对其进行操作(我认为boost::dynamic_bitset也可以在没有迭代器类的情况下立即执行此操作) -
不错的建议,但
std::bitset如果你知道如何正确使用它会非常强大!
标签: c++ stream c++-standard-library c++20 std-bitset