【问题标题】:A general question about possible future C++ language or standard library features regarding bit streams关于比特流可能的未来 C++ 语言或标准库功能的一般问题
【发布时间】: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 对象,例如iostreamfstreamsstream 等,我们可以将各种数据类型的值馈送到这些流中,读取或写入字符串流、文件流,到控制台或终端的 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 和其他流库一样,通过使用&lt;iomanip&gt; 库,我们可以使用格式修饰符将输入或输出分解为任何指定长度的离散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&lt;bool&gt; 并创建一个 bitset_iterator 并对其进行操作(我认为 boost::dynamic_bitset 也可以在没有迭代器类的情况下立即执行此操作)
  • 不错的建议,但std::bitset如果你知道如何正确使用它会非常强大!

标签: c++ stream c++-standard-library c++20 std-bitset


【解决方案1】:

这已经如你所愿:

std::cout << byte << word << dword << qword;

std::cin >> odd5 >> odd3 >> odd7;

对于中间存储,可以简单地使用std::stringstream,它也可以按照您的描述工作。

但是没有字节序,因为操作是按位的,而不是按字节的。

【讨论】:

  • 我知道您可以将bitset 传递给现有的流。我只是想知道是否有任何概念只为bitsets 拥有一个特定的流对象!这意味着bitsetbitstream 之间存在耦合,因为bitstream 对象只能与bitset 类型或其他stream 对象一起使用...
  • @FrancisCugler 我不明白你看到的目的是什么。您能描述一个无法通过已经可能解决的用例吗?
  • @FrancisCugler 此外,C++ 流应该表示字符输入/输出的目标或源(即它继承自 std::ostreamstd::istream)。您的std::bitstream 与此相符吗? std::bistream 将如何存储字符?例如。 bs &lt;&lt; "Hello world!"; 的结果是什么,它与 std::stringstream 有何不同?
  • @FrancisCugler 那么看来您正在寻找的实际上只是std::bitset 的动态大小版本,其中operator&lt;&lt;/operator&gt;&gt; 为连接和提取而重载,类似于boost::dynamic_bitsetstd::vector&lt;bool&gt;。这些都没有您需要的所有功能,但可以轻松扩展到。
  • @FrancisCugler 这只是为(dynamic_bitset&amp;, std::bitset&lt;N&gt;&amp;) 参数(目前似乎没有)提供&lt;&lt;/&gt;&gt; 重载的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
相关资源
最近更新 更多