Boost logo

Boost :

From: Jonathan Turkanis (technews_at_[hidden])
Date: 2005-01-10 19:46:12


Philippe Mori wrote:

>> ... is there any reason to prefer functions with the signature
>>
>> void (*) () [A]
>
> This is too much strict to force the uses of cin and cout... Any other
> possible uses would require either to redirect inputs (which might not
> always be possible particulary if there are multiple thread or if some
> code assumes that cin or cout is the standard output and can be used
> freely).

I'm still looking for an example showing that it's useful at all.

>> over member functions taking references to an input stream and an
>> output stream:
>>
>> struct myfilter {
>> void filter(std::istream&, std::ostream&); [B]
>> };
>>
>> This is more in keeping with the reset of the library.
>
> This is better, but why not uses operator() instead of a named
> function since it would allows us to uses ordinary function of function
> object and it will works well with boost::function.

All the filter and device concepts are formulated in terms of ordinary functions
rather than operators. This is so that read, write, close etc. can be
distinguished. If there were lots of existing function object types lying around
which took references to an istream and an ostream and had the correct
semantics, it might be worth providing direct support for them. But I don't know
of a single example. Also, I can't see how you would use boost::function here.

>> Finally, why shouldn't the signature be:
>>
>> struct myfilter {
>> template<typename Source, typename Sink>
>> void filter(Source& src, Sink& snk);
>> [C]
>> };

> This, combined with my suggestion of using operator() would be the
> best solution in my opinion. But if the Source and Sink can have arbitrary
> type we should have a bunch of traits that would allows the code to works
> with most or all type of Source and Sink.

The Source and Sink concepts are well defined. You access them using the
functions boost::io::read, boost::io::write(), etc.

> OTOH, if someone only need to support one kind of stream in it
> algorithm then it might prefer to implement the non-template version.

Again, I haven't yet seen a single convincing example of either, so I'm in no
position to judge which is preferable. What I'm looking for is a case where it's
significantly easier to write a filter like so

>> struct myfilter {
>> void filter(std::istream&, std::ostream&); [B]
>> };

than using one of the existing types of filters, such as input filter, output
filter or symmetric filter.

>>> ...Is there any reason why
>>> the source() and sink() can not be assumed to be cin and cout
>>> respectively when absent?
>>
>> Yes. When you use the pipe operator you don't always want to form a
>> complete
>> chain:
>>
>> filtering_ostream out(filter1() | filter2() |
>> filter3()); out.push(sink());
>>
> Well passing filters to the constructor might be more limitating that
> working with objects.

I don't follow.

> So I thing we should be able to do something
> like:
>
> filtering_ostream out;
> out < cin;
> out | filter1() | filter2();
> out | filter3();
> out > cout;

Okay, but what is it supposed to do? ;-)

> Philippe

Jonathan


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk