代码之家  ›  专栏  ›  技术社区  ›  Jon Purdy

如何扩展std::basic_streambuf以将任何可引用序列视为流?

  •  0
  • Jon Purdy  · 技术社区  · 14 年前

    注意:根据回答进行编辑,以获得更合适的答案。

    我有一个C++模板的集合,这些模板是我多年来制作的,我称之为Joop.它主要包括那些不完全属于“通用”类别,但足够有用的库,我不断地将它们放入不同的项目中,因此它们中的大多数在其他库中没有类似的库,如boost。

    其中一个班是 seqstream . 其思想是,它允许您将任何可ITerable序列视为一个普通的类似STL的流,其“字符类型”是序列的值类型。

    这门课的基本原理是双重的。首先,它应该呈现一个接口,使任何潜在的非线性、非连续序列看起来是线性的和连续的;其次,它应该将流中的任何对象视为单个、复杂、大字符。有一种标准的方法可以将流视为序列,那么为什么不采用另一种方法呢?

    目前, SEQFISH 包装第一个、最后一个和当前元素的三个迭代器。我想换一个 SEQFISH 用一个 basic_seqbuf 可以插入到标准流中。有人能提供资源让我开始扩展 std::basic_streambuf 提供这种行为?

    此外,如果可写 seqbuf 是允许的,这是非常重要的 塞克布夫 将对象序列化,但对 insert() 方法或使用用户指定的插入迭代器,例如 std::back_insert_iterator .

    编辑:

    下面是一个如何 SEQFISH 当前使用:

    // Create a sequence of objects.
    std::vector<std::string> sequence;
    for (int i = 0; i < 10; ++i) {
        std::ostringstream stream;
        stream << "Element " << i << ".";
        sequence.push_back(stream.str());
    }
    
    // Create a seqstream wrapping that sequence.
    joop::seqstream< std::vector<std::string> > seqstream(sequence.begin(), sequence.end());
    
    // Read the sequence like a stream.
    std::string element;
    while (seqstream >> element) // OR seqstream.get(element)
        std::cout << element << '\n';
    
    1 回复  |  直到 14 年前
        1
  •  1
  •   Potatoswatter R. Martinho Fernandes    14 年前

    sstream 但您可能根本不需要新的流类。现在寻找一个例子 basic_stringstream 源,该类的唯一目的是

    • 提供 str 函数(它只调用底层缓冲区的 STR )
    • 在调用基础缓冲区的方法时避免使用其vtable
    • 改变 rdbuf 的返回值 basic_stringbuf* (但这是不必要的,因为 STR 提供)

    流类做的很少,而且除了调用类型的底层缓冲区之外,实际上不应该有任何功能。 basic_streambuf . 例如,我可以这样做:

    string str( "Hello, world!" );
    stringbuf buf( str ); // subclass of basic_streambuf
    iostream pseudo_stringstream( &buf );
        // pseudo_stringstream can do anything a stringstream can do.
        // (not necessarily with the same syntax)
    

    而且,所有的流都应该继承自 basic_istream , basic_ostream 或两者兼而有之。如果流未正确继承,则插入器/提取器函数可能无法工作。这些插入器声明非常好:

    operator<<( ostream os, MyData d ); // not a template at all
           // templated, but requires correct inheritance:
    template< class C > operator<<( basic_ostream<C> os, MyData d );
    

    因此,如果需要iostream行为,则需要实现 基本流苏 并将其连接到 basic_iostream .


    但是,你的实际目标是什么?与通常的迭代器相比,内存支持流的优势是什么,也许还有一些 back_insert_iterator S?是否要使用与迭代相同的代码进行序列化?您可能希望使流看起来像使用 stream_iterator ,而不是使序列看起来像流。