2010-08-21 2 views
1

У меня есть проект производителя/потребителей в моем приложении, которые реализуют функции Produce/Consume для пользовательских типов. Но это не работает очень естественно со стандартной библиотекой и особенно с алгоритмами.C++ и Enumerable

В C# есть Переменные и Наблюдаемые понятия, которые могут быть использованы для простого использования таких вещей и получения большой свободной функциональности.

В C++ существуют концепции ios, istream, ostream, input_iterator, output_iterator, которые, как я думал, могут быть полезны. Но мне кажется, что все они предназначены для примитивных типов символов, например. char, int и т. д., но не для пользовательских типов.

Конечно, я мог бы использовать настоящие функции, такие как Produce/Consumer и std :: mem_fn для алгоритмов. Но я надеялся, что есть лучший способ.

Я смотрю несколько советов о том, как идти о проектировании i/o подобных решений по типам пользователей на C++.

E.g. от C#

class FrameProducer : IEnumerable<Frame> // pull frames 
{...} 

// Some engine between 

class FrameConsumer : IObserver<Frame> // push frames 
{...} 

Я надеялся на что-то подобное на C++, например. которые, я считаю, не возможны.

class FrameProducer : istream<Frame> // pull frames 
{...} 

// Some engine between 

class FrameConsumer : ostream<Frame> // push frames 
{...} 

Возможно, я думаю об этом трудно и должен просто идти КИС.

Мысли?

+0

Почему вы говорите о C#? Это C++, забудьте, что вы знаете C# и начинаете программирование на C++. Говоря «Я бы сделал это так на языке X, как я могу перевести его на язык Y» всегда будет терпеть неудачу, вы должны выучить язык Y с нуля, чтобы вы знали, как все делается на языке Y. [Хорошая книга помогает] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). О, и я не понимаю. Всякий раз, когда вы вводите язык X в проблему языка Y, многие люди, которые знают язык Y, нуждаются в разъяснении этой функции языка X. – GManNickG

+0

Можете ли вы лучше объяснить, что вы подразумеваете под «Произвести/Потреблять функции на пользовательских типах»? – Dacav

+0

Не имеет значения, на каком языке я говорю, это не так. Я просто выбрал C#, потому что это было удобно, поскольку у него была концепция LINQ, которая похожа на C++ и ее итераторы и алгоритмы. Мой вопрос в том, почему концепция C++ ios не позволяет использовать типы пользователей и какие существуют альтернативы. – ronag

ответ

3

Th термины являются «оператором ввода» и «оператором извлечения», которые вставляют и извлекают данные из потока.

Вот пример:

#include <iostream> 
#include <sstream> 

struct foo 
{ 
    int x; 
}; 

// insertion operator 
std::ostream& operator<<(std::ostream& s, const foo& f) 
{ 
    s << f.x; // insert a foo by inserting x 
    return s; 
} 

// extraction operator 
std::istream& operator>>(std::istream& s, foo& f) 
{ 
    s >> f.x; // extract a foo by extracting x 
    return s; 
} 

int main(void) 
{ 
    std::stringstream ss; 

    foo f1 = {5}; 
    ss << f1; 

    foo f2; 
    ss >> f2; 
} 

На основании вашего желания сделать:

MyFrameProducer producer; 
MyFrameConsumer consumer; 
Frame frame; // frame should probably be in the while loop, since its 
while(!producer.eof()) // lifetime doesn't need to exist outside the loop 
{ 
    producer >> frame; 
    consumer << frame; 
} 

Вы могли бы сделать:

struct MyFrameProducer {}; // add an eof function 
struct MyFrameConsumer {}; 
struct Frame {}; 

// producer produces a frame 
MyFrameProducer& operator>>(MyFrameProducer& p, Frame& f) 
{ 
    /* whatever it takes to make a frame */ 

    return p; 
} 

// consumer consumes a frame 
MyFrameConsumer& operator<<(MyFrameConsumer& c, const Frame& f) 
{ 
    /* whatever it takes to use a frame */ 

    return c; 
} 

Или что-то похожее на это. (Извините, мое понимание проблемы невелико.) : немного странно, желая этого интерфейса, поскольку он не имеет ничего общего с потоками, и вам может быть лучше с другим интерфейсом (явные методы).

+0

Не совсем, то, что вы показываете, - это преобразование типа пользователя в строку. Я искал что-то вроде этого (который не работает с СТЛ IStream/ostream, кажется, персонаж на основе) класса MyFrameProducer: IStream { } класса MyFrameConsumer: ostream { } int main() { MyFrameProducer производитель; MyFrameConsumer потребитель; Рама; while (! Производитель.eof()) { производитель >> рама; потребитель << рама; } } – ronag

+1

@ronag: Я не * показывал, как преобразовать пользовательский тип в строку, я показал, как вставить его в поток. (Только по совпадению «stringstream» предоставляет способ создания строки.) Позвольте мне отредактировать ответ на ваш фрагмент комментария. – GManNickG

+0

Я что-то исправил, но теперь это сообщество wiki, извините. – Philipp

2

Посмотрите на this решение производителя/потребителя. Хотя он в чистом C, он настолько изящный, поэтому я просто не могу удержаться от его публикации.

+1

Интересно, это тоже интересно: http://www.crystalclearsoftware.com/soc/coroutine/ – ronag

Смежные вопросы