如何在C ++中编写自定义流转换?

时间:2014-10-11 10:06:46

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

我在使用Haskell和函数式语言之后学习了很多C ++,我发现我一直在努力解决同样的问题:

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

如果这是Haskell,我可以简单地利用一切都是懒惰的事实,并在我考虑它时编写我的转换,然后它将在下游被消耗时应用。甚至有一些库可以执行这种精确模式(conduitpipes)。

假设我想采用序列1 2 3 4 5 6 ...并输出12 34 56 ...。我可以看到如何编写在流上运行的ad-hoc代码并处理数据到位。但我想知道是否有一个抽象机制允许我通过从另一个流转换数据(以任何可想到的方式)来构建新流。这个抽象应该允许我缓冲数据因为我正在处理它,而不仅仅是将单个元素简单映射到新值。

以下是限制:

  • 我不能使用stdlib以外的任何其他库。
  • 它必须适用于C ++ 03 (意味着没有C ++ 11功能。)

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

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

2 个答案:

答案 0 :(得分:2)

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

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;
}

答案 1 :(得分:0)

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

David Sankel在2014年的C ++中使用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 with stream迭代器应该主要做你需要的。