Topic: stream iterators in place of container iterators


Author: jeet_sukumaran@my-deja.com
Date: 1999/10/25
Raw View
In article <3813cd4d.0@202.66.196.251>,
  "Andrei Alexandrescu" <andrewalex@hotmail.com> wrote:
> The answer is: the code is legal. However, MSVC lacks support for
> member template functions (or, better said, it supports them, but in a
> buggy manner), so MSVC's std lib doesn't define them.

Hello Andrei.

Thanks for the reply.

But I'm not sure if I understand you.  Exactly which part of the code
uses member template functions? As given, the classes are concrete.
the "std::istream_iterator<DATA_T>" you see in the parameter lists
refer (of course) to the argument variables that will be passed to the
functions -- the constructor and the stream setter respectively.  Do
you mean std::vector::assign()?  I know that this is a _template member
function_, but is it a _template member template function_?

As far as I can tell, my code neither makes use of nor interacts with
template member functions in any way (though it does make use of
template classes of course) ... am I completely off by thinking this?

I've included the code again for clarification:

class Sample {

public:
    typedef double DATA_T;

    // ..
    Sample(std::istream_iterator<DATA_T> begin,
       std::istream_iterator<DATA_T> end);

    // ..
    std::istream& setFromStream(std::istream_iterator<DATA_T> begin,
       std::istream_iterator<DATA_T> end);

private:
    std::vector<DATA_T> data_;

};


Sample::Sample(std::istream_iterator<DATA_T> begin,
              std::istream_iterator<DATA_T> end)
    : data_(begin, end) {

}


Sample::setFromStream(std::istream_iterator<DATA_T> begin,
              std::istream_iterator<DATA_T> end) {

    data_.assign(begin, end);

}


As to MSVC not implementing member templates -- well, if it were just
MSVC rejecting the code, I'd have no problems.  In fact, there are days
when I am amazed that MSVC did, in fact, handle a particular bit of
conforming code correctly.  However, Borland's rejection is matter for
real concern.  I have a lot of respct for them -- their compiler is
quite conformant, and their STL (RogueWave's) is quite complete.  I
like and have a whole lot of respect for gcc too, but gcc's relaxed
attitude toward the code precludes any chance of it being used to
decide the legality of constructions in the code.

Well, let me know if I'm even more confused than I thought I was.

-- jeet


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1999/10/25
Raw View
jeet_sukumaran@my-deja.com wrote:
...
> functions -- the constructor and the stream setter respectively.  Do
> you mean std::vector::assign()?  I know that this is a _template member
> function_, but is it a _template member template function_?

It's templated on the iterator type used as input.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Salters <salters@lucent.com>
Date: 1999/10/27
Raw View
jeet_sukumaran@my-deja.com wrote:
>
> folks --
>
> I hope you don't get too tired of these "is this legal" questions ...
>
> Can the stream iterators be used anywhere iterators are called for (as
> long as directionality -- input/output -- and const'dness are adhered
> to)?

No. A forward iterator may be written to twice between incrementing;
the second write will overwrite the value first stored. It's easy
to imagine an stream iterator to a pipe (unbuffered), which has
already sent out the object. Therefore, stream iterators are the
lowest of the iterators.

> Here's some code --

> class Sample {

> public:
>     typedef double DATA_T;

>     // ..
>     Sample(std::istream_iterator<DATA_T> begin,
>        std::istream_iterator<DATA_T> end);

>     // ..
>     setFromStream(std::istream_iterator<DATA_T> begin,
>        std::istream_iterator<DATA_T> end

// Missing a ')' and possibly more ?

> private:
>     std::vector<DATA_T> data_;

> };

> Sample::Sample(std::istream_iterator<DATA_T> begin,
>               std::istream_iterator<DATA_T> end)
>     : data_(begin, end) {
> }

> Sample::setFromStream(std::istream_iterator<DATA_T> begin,
>               std::istream_iterator<DATA_T> end) {
>     data_.assign(begin, end);
> }

> Gcc 2.95 has no problems with it (no surprise there -- the things it
> lets you get away with!).  Both MSVC and Borland don't like it.  I
> thought that stream iterators could be used anywhere an iterator is
> called for.

"anywhere an input/output(*) iterator is called for"
(*) as appropriate. Of course, an istream iterator cannot be used
as an output iterator.

> Stroustrup implies so, unless I've misinterpreted him: "this [the
> ostream_iterator] accepts the usual write and increment operations of
> an output iterator and converts them into output operations on an
> ostream" and "This iterator [the istream_iterator] is specified so that
> what would be conventional use for container triggers input fom an
> istream" (pgs 558, 559 from the C++PL, 3rd ed).

Conventional use being *it; it++; *it; it++; etc; (etc; ? I'm making
a statement. I assume data_.assign(begin, end) is troubling ? Or is it
the constructor (with data_(begin, end)) ?

The constructor of data_ should take two input iterators. However, the
algorithm required is different for input iterators, since they may
force reallocations (no way to determine input size). It is possible
that this algorithm is broken.

The same applies to assign, so it should compile, too.

> Is this an example of non-conformance by the Borland and MSVC
> compilers? I just finished a small program that compiled and ran under
> gcc.  Borland and MSVC pitched a royal fit.  Some of it quite
> justified.  For example, gcc blissfully let this pass:
>
>     std::copy(v.begin(), v.end(), data_); // !!!!

> Where v is a std::vector<DATA_T>.

That's a bit uncalled for. Did it run ?

> I should have used "std::back_inserter(data_)" instead of "data_" of
> course.  And gcc should have told me!  Some really atrocious and
> dangerous code was passed by gcc.  Never mind that -- mea culpa for the
> bad code, and praise to the other compilers for doing their job.  The
> thing is, I've fixed almost everything, except the above two
> constructions.  As best as I can make out, they are legal however.

I tend to agree. What did MSVC say, and Borland? That might give us a
hint to what's wrong.

> So now I am in a quandry.  I don't have sufficient expertise or
> proficiency to figure out which is right and which is wrong (in either
> case they will be broken under one compiler or another) -- and I'm just
> wondering, for future reference which way to go.

Me too. Post the error message.
(Actually the first time I wrote that. Hope the moderators don't
 have a filter against metoo's :)

--
Michiel Salters
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jeet_sukumaran@my-deja.com
Date: 1999/10/24
Raw View
folks --

I hope you don't get too tired of these "is this legal" questions ...

Can the stream iterators be used anywhere iterators are called for (as
long as directionality -- input/output -- and const'dness are adhered
to)?

Here's some code --

class Sample {

public:
    typedef double DATA_T;

    // ..
    Sample(std::istream_iterator<DATA_T> begin,
       std::istream_iterator<DATA_T> end);

    // ..
    setFromStream(std::istream_iterator<DATA_T> begin,
       std::istream_iterator<DATA_T> end

private:
    std::vector<DATA_T> data_;

};


Sample::Sample(std::istream_iterator<DATA_T> begin,
              std::istream_iterator<DATA_T> end)
    : data_(begin, end) {

}


Sample::setFromStream(std::istream_iterator<DATA_T> begin,
              std::istream_iterator<DATA_T> end) {

    data_.assign(begin, end);

}

Gcc 2.95 has no problems with it (no surprise there -- the things it
lets you get away with!).  Both MSVC and Borland don't like it.  I
thought that stream iterators could be used anywhere an iterator is
called for.

Stroustrup implies so, unless I've misinterpreted him: "this [the
ostream_iterator] accepts the usual write and increment operations of
an output iterator and converts them into output operations on an
ostream" and "This iterator [the istream_iterator] is specified so that
what would be conventional use for container triggers input fom an
istream" (pgs 558, 559 from the C++PL, 3rd ed).

Is this an example of non-conformance by the Borland and MSVC
compilers? I just finished a small program that compiled and ran under
gcc.  Borland and MSVC pitched a royal fit.  Some of it quite
justified.  For example, gcc blissfully let this pass:

    std::copy(v.begin(), v.end(), data_); // !!!!

Where v is a std::vector<DATA_T>.

I should have used "std::back_inserter(data_)" instead of "data_" of
course.  And gcc should have told me!  Some really atrocious and
dangerous code was passed by gcc.  Never mind that -- mea culpa for the
bad code, and praise to the other compilers for doing their job.  The
thing is, I've fixed almost everything, except the above two
constructions.  As best as I can make out, they are legal however.

So now I am in a quandry.  I don't have sufficient expertise or
proficiency to figure out which is right and which is wrong (in either
case they will be broken under one compiler or another) -- and I'm just
wondering, for future reference which way to go.

People -- I will appreciate ANY help on this matter.  I've looked up
the headers, looked at the Dinkum site, and looked at Stroustrup.  I
*think* the constructions are right.  MSVC and Borland don't.  Three
hours ago, I would have gone with my interpretation of what is right
(esp. when faced with _MSVC_ arguing with me).  This gcc to
MSVC/Borland test migration, however, has shaken my faith
considerably.  Not to mention that I actually churned out something
like dropping std::back_inserter -- that's gotta hurt the ego!  And
some of the other horrors that were in my code before I fixed them ...
well, better left unsaid.

Anyway, please advise.

-- jeet


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/10/25
Raw View
<jeet_sukumaran@my-deja.com> wrote in message
news:7ustoj$vv0$1@nnrp1.deja.com...
[snip]
> Sample::Sample(std::istream_iterator<DATA_T> begin,
>               std::istream_iterator<DATA_T> end)
>     : data_(begin, end) {
>
> }
>
>
> Sample::setFromStream(std::istream_iterator<DATA_T> begin,
>               std::istream_iterator<DATA_T> end) {
>
>     data_.assign(begin, end);
>
> }
>
> Gcc 2.95 has no problems with it (no surprise there -- the things it
> lets you get away with!).  Both MSVC and Borland don't like it.  I
> thought that stream iterators could be used anywhere an iterator is
> called for.

The answer is: the code is legal. However, MSVC lacks support for
member template functions (or, better said, it supports them, but in a
buggy manner), so MSVC's std lib doesn't define them.


Andrei
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]