【问题标题】:How can I write a custom stream transformation in C++?如何在 C++ 中编写自定义流转换?
【发布时间】:2014-10-11 10:06:45
【问题描述】:

在使用 Haskell 和函数式语言进行了大量工作后,我正在学习 C++,我发现我一直在尝试解决同样的问题:

  • 从输入流中读取一些数据
  • 根据特定算法对它们进行标记
  • 处理令牌

如果这是 Haskell,我可以简单地利用一切都是惰性的这一事实,并根据我的想法编写我的转换,然后在下游被消耗时应用它。甚至有一些库可以做到这一点(conduitpipes)。

假设我想获取序列1 2 3 4 5 6 ... 并输出12 34 56 ...。我可以看到如何编写对流进行操作并就地处理数据的临时代码。但我想知道是否有一种抽象机制允许我通过从另一个流转换数据(以任何可能的方式)来构建一个新流。这种抽象应该允许我缓冲数据在我处理它时,不仅仅是将单个元素简单映射到新值。

以下是限制:

  • 我不能使用除 stdlib 之外的任何其他库。
  • 它必须在 C++03 上工作(意味着没有 C++11 功能。)

如果你在想,这是一个家庭作业吗?好吧,我有很多课堂作业需要我处理数据流(这就是没有库和 C++03 限制)。不是我不知道如何使用while循环来做到这一点,而是我想知道stl中是否存在现有的流抽象,只是等待被发现和使用。

但如果这样做的唯一方法是使用 C++11,那么我想知道。

【问题讨论】:

  • 没有我知道的现成包。也许是与std::istream_iterator 一起使用的自定义类类型?
  • @T.C.嗯,这可能是我正在寻找的。如果我理解正确,我会实现一个自定义迭代器,它接受输入流,并产生我需要的输出?如果我想使用一个迭代器并从中构建另一个迭代器(想想组合)怎么办?
  • 我在考虑一个带有自定义流提取运算符的类,与std::istream_iterator 一起使用。至于组合,您需要编写自己的迭代器适配器。

标签: c++ stream c++03 c++98 stream-processing


【解决方案1】:

概念代码,未经测试。 成像有很多错误检查和正确的语法。

struct add : public std::binary_function<int,int,int> {
  int operator() (int a, int b) {return (a + b);}
};

template<typename inType, typename dType, typename outType, class binFunc>
outType Transformer(inType& inStream, outType& outStream, binFunc func) {
  dType a, b;
  // Read some data from an input stream
  // Tokenize them based on a specific algorithm
  inStream>> a >> b; 
  //outStream << func(a, b);
  return func(a,b); // Process the tokens
}

int main() {
  std::ifstream in("input.dat", std::ifstream::in); // , std::ios::binary
  std::ofstream out("output.dat");
  struct add adder;  // to Process the tokens

  out << Transformer(in, out, adder);

  return exit_success;
}

【讨论】:

    【解决方案2】:

    以下内容不符合您对无库解决方案的需求(而且我没有足够的声誉将其作为评论留下);但是,它对您的功能性思维方式会很方便。

    David Sankel 在 C++Now 2014 上发表了关于使用 C++ 的 FRP 的精彩演讲。他甚至提供了他们用于生产的库。

    视频可以在这里找到:https://www.youtube.com/watch?v=tyaYLGQSr4g&list=UU5e__RG9K3cHrPotPABnrwg

    幻灯片链接在幻灯片末尾的视频描述和 github 链接上。

    我猜你也会从这里得到灵感: http://ericniebler.com/2013/11/07/input-iterators-vs-input-ranges/

    std::transform 与流迭代器应该在很大程度上满足您的需求。

    【讨论】:

      猜你喜欢
      • 2012-12-14
      • 2011-04-06
      • 1970-01-01
      • 2014-07-05
      • 2010-10-21
      • 1970-01-01
      • 2011-05-13
      • 1970-01-01
      相关资源
      最近更新 更多