Как я могу написать собственное преобразование потока в C ++?

Я изучаю C ++ после того, как много работал с Haskell и функциональными языками в целом, и обнаружил, что постоянно пытаюсь решить одну и ту же проблему:

  • Читать некоторые данные из входного потока
  • Токенизируйте их на основе определенного алгоритма
  • Обрабатывать токены

Если бы это был Haskell, я мог бы просто воспользоваться тем фактом, что все лениво, и написать свое преобразование, когда я об этом думаю, и тогда оно будет применено по мере использования нижестоящего потока. Есть даже библиотеки, которые делают этот точный образец (трубопровод а также трубы).

Допустим, я хотел взять последовательность 1 2 3 4 5 6 ... и вывод 12 34 56 ..., Я вижу, как написать специальный код, который работает с потоком и обрабатывает данные на месте. Но я хотел бы знать если есть механизм абстракции, который позволяет мне создавать новый поток путем преобразования данных (любым мыслимым способом) из другого потока. Эта абстракция должна позволять мне буферизовать данные во время их обработки, а не просто отображать отдельный элемент в новое значение.

Вот ограничения:

  • Я не могу использовать любую другую библиотеку, кроме stdlib.
  • Это должно работать на C ++ 03 (имеется ввиду отсутствие функций C ++ 11.)

Если ты думаешь, это домашняя работа? Ну, вроде, я получаю много заданий класса, которые требуют от меня работать с потоками данных (что является причиной нет ограничений библиотеки и C ++ 03). Дело не в том, что я не знаю, как это сделать, используя while циклы, но я хотел бы знать, существует ли существующая потоковая абстракция в stl, просто ожидающая обнаружения и использования.

Но если единственный способ сделать это — использовать C ++ 11, то я хотел бы знать.

4

Решение

Концептуальный код, не проверенный.
Визуализация там много ошибок, проверка и правильный синтаксис.

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) выступил с прекрасным докладом по FRP с использованием C ++ на C ++ Now 2014. Он даже предоставил библиотеку, которую они используют для производства.

Видео можно найти здесь: https://www.youtube.com/watch?v=tyaYLGQSr4g&список = UU5e__RG9K3cHrPotPABnrwg

Слайды связаны с описанием видео и ссылками на github в конце слайдов.

Я подозреваю, что вы также получите вдохновение здесь:
http://ericniebler.com/2013/11/07/input-iterators-vs-input-ranges/

std :: transform с потоковыми итераторами должен делать то, что вам нужно.

0

По вопросам рекламы [email protected]