Re: How do we use an ifstream vector?
On Feb 2, 1:39 pm, "Alf P. Steinbach" <al...@start.no> wrote:
* James Kanze:
On Feb 2, 12:30 am, "Alf P. Steinbach" <al...@start.no> wrote:
* maria:
[...]
typedef boost::shared_ptr< std::ifstream > IfStreamPtr;
std::vector<IfStreamPtr> in;
For once:-). Agreed. This is one place where shared_ptr is
just the ticket. (Of course, the next version of the standard
will support move semantics, and will allow a vector of
ifstream. But I wouldn't count on it any time soon.)
State which other uses you think have been inappropriate.
Most. There seems to be a mode for using shared_ptr everywhere.
In practice, it's only appropriate in particular situations.
Or, from a practical point of view, to avoid having to deal
with all that, but also then coding without a safety net,
just use a raw array of ifstream, default-initialized, and
then open() each one.
I'm not sure where the problem with that is, if the array is a
local object. With g++, at least, unless you're compiling with
the options I mention above, you don't have any safety net with
vector, either, and with Sun CC (with either the Rogue Wave
version of the library or the STL port), there aren't even any
options to provide the safety net.
There is a safety net.
Where?
If you don't want that safety net, then use the C standard
library's functionality instead.
It's hard to define an array of a type which has a user defined
constructor in C.
It's even more convenient for this, not to mention, usually
more efficient.
Sorry, I don't understand. How is C more convenient for an
array of std::ifstream?
[...]
This code does some ungood things such as using a magic number
(namely 5) and using ifstream pointers rather than abstracting
up to istream. I couldn't recall whether istream has virtual
destructor or not.
Are you kidding? All classes in the standard which have virtual
functions have a virtual destructor. (In this case, the base
class ios_base has a virtual destructor.)
Nope, I'm not kidding, and I'm not assuming anything iostream
is reasonable.
More FUD. Just because you don't want to bother to learn
something new.
You really should stop spreading FUD about iostream. If you
don't like them, don't use them, but they happen to be the best
alternative by far that we have, and used correctly, the
actually work very well.
Write me that old copy-standard-input-to-output-exactly
program, portably for the platforms supporting that (Windows
and Unix suffices).
Formally, of course, it can't be done, either in C or in C++.
Practically, open both files in binary mode, and:
out << in.rdbuf() ;
does the trick in C++.
I fail to see the problem. Just because you've decided that you
want to be intentionally dense is no reason.
This demonstrates that instead of -- as you maintain --
working well, there are trivial and very reasonable and very
practically useful problems for which they don't work at all.
IO streams, like the C FILE*, are designed around a particular
abstraction. For historical reasons (like FILE*), they support
other functionality, but less well. If you need a tool
implementing that abstraction, iostream is several orders of
magnitude better than FILE*. If you need a tool implementing
something else, then iostream may not be the answer. No tool
can be perfect for everything.
It's perhaps worse for the problems where they sort of work,
e.g. giving a false sense of security, being maddeningly
baroch and archaic, requiring overly verbose client code,
often being grossly inefficient, etc. ad nauseam, including
having two-phase initialization both externally and
internally, having hidden modes and failure state, and
exhibiting Undefined Behavior at the slightest provocation,
when safety was the problem they were meant to address.
Are you being intentionally dense, or just stupid. The above is
just name calling, with no justification in fact, as you well
know.
In short, the so-called /abstraction cost/ seems to be high
for this problem, but might be alleviated by using more
suitable library classes.
More FUD. The only abstraction cost is the extra
allocations of std::vector. Probably not even measurable,
compared to the time used to read a file.
Simply compare (1) the code size, (2) the complexity of the
code, and, although it doesn't matter in practice here, (3)
the (in-) efficiency (which contrary to what you state also
include dynamic allocations of ifstreams and dynamic
allocations inherent in using boost::shared_ptr).
Abstraction cost is not only ineffiency.
The only one really relevant is the complexity at the user
level. It is slightly more complex to have to explicitely
allocate (using a new expression) each of the ifstream, rather
than let the compiler handle it automatically, e.g.:
std::ifstream inputs[ 10 ] ;
For the rest, I doubt that the differences are measurable.
This is another example of you being not right (wrt. previous
comments).
I wouldn't talk about being right if I were you. Given the
number of idiocies you spout off about iostream.
The raw array and non-exception-based version:
#define ARRAY_SIZE( a ) (sizeof(a)/sizeof(*a))
bool foo()
{
using namespace std;
static char const* const inFileNames[] = { "a", "b", ... };
ifstream inFiles[ARRAY_SIZE(inFileNames)];
assert( ARRAY_SIZE(inFileNames) >= 5 );
for( int i = 0; i < 5; ++i )
{
if( !inFiles[i].open( inFileNames[i] ) )
{
return false;
}
}
// Do things with the files, then:
return true;
}
Still more FUD. The above is perfectly exception safe. The
only problem it has is that it isn't the usual idiom, so the
reader will ask why.
Yes, it's correct that your comment here is more FUD. :-)
Nobody's said it wasn't exception safe.
And what does your words "non-exception-based" version mean?
And nobody (except you) have claimed it is.
What got into you?
Just sick and tired of your incompentent idiocies. There are
things you know well, but iostream isn't one of them.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34