C ++:使用std :: cin的多个副本?

时间:2017-02-24 21:01:16

标签: c++ stdin istream noncopyable

我正在编写一个简单的通用解析器组合库。这意味着该库包含许多小函数对象,称为解析器,(在调用时)将字符串作为输入并返回ParseResults列表作为输出,其中ParseResult是

template <typename A> using ParseResult = std::pair<A, std::string> 如果解析器不匹配,则列表为空,如果匹配,则包含单个结果,并且可能以多种(模糊)方式匹配的某些解析器可能返回更多结果。

但是,这意味着现在正在进行大量的字符串复制。此外,在开始时,需要使用字符串调用最终构造的解析器,因此所有std::cin(或文件的合并内容)都将复制到字符串中。

看起来更好的主意(因为解析器只查看字符串当前前面的第一个(少数)字符),就是在标准输入流中跟踪你现在的位置。我相信这正是std::istream的意思。但是,istreams不可复制。我的问题怎么解决? 有没有办法返回一个istream的副本,指向原始点所在的几个字符?或者是否有另一种更清洁的方法来解决这个问题?

1 个答案:

答案 0 :(得分:1)

这个问题可以这样重写:你如何以避免过度复制并允许输入流的方式表示未解析部分的输入?

最灵活的方法是用迭代器表示它。如果解析器进行回溯,则需要ForwardIterator,如果不是,InputIterator就足够了。这意味着您可以直接使用std::istream_iterator而不是std::cinstd::ifstream,或者从内存中的std::stringschar数组进行解析。使用回溯的流更复杂,需要您编写缓冲迭代器适配器,将InputIterator转换为std::istream_iteratorForwardIterator,或者编写直接包装std::ifstream的迭代器,在你需要回溯时做.seekg()

另一种选择是使用C ++ 17的std::string_view,它不会复制,并且具有一个很好的,解析友好的界面。虽然这不能解决流式传输问题,但您仍需要先读取整个文件。