Initializing an istream to either of two streams

J

jacek.dziedzic

Hi!

I have a function that, depending on a boolean condition, should
read data from either an ifstream or a stringstream. Passing the
respective stream to the function by reference or pointer is out of
the question. I already have the function for the ifstream version, so
instead of writing everything twice, I wanted to take a shortcut:

// ifs is the ifstream, ss is the stringstream
istream input (use_stringstream ? ss : ifs);

input >> ...
getline(input,s); ...

This, however, doesn't work, because streams cannot be copied. So I
tried with
istream& input (use_stringstream ? ss : ifs);

but I need an lvalue when I want to assign to a reference...

A const-reference is no good, because I work on the stream later on,
changing its state.

Is there any way I could do it?

TIA,
- J.
 
M

Michael DOUBEZ

(e-mail address removed) a écrit :
I have a function that, depending on a boolean condition, should
read data from either an ifstream or a stringstream. Passing the
respective stream to the function by reference or pointer is out of
the question. I already have the function for the ifstream version, so
instead of writing everything twice, I wanted to take a shortcut:

// ifs is the ifstream, ss is the stringstream
istream input (use_stringstream ? ss : ifs);

input >> ...
getline(input,s); ...

This, however, doesn't work, because streams cannot be copied. [snip]
Is there any way I could do it?

Use a reference:
istream& input=use_stringstream ? ss : ifs;
 
J

jacek.dziedzic

Use a reference:
istream& input=use_stringstream ? ss : ifs;

Yes, I tried that, and wrote about it in the remainder of my post.

The problem with the reference was that I need an lvalue on the
right hand side.

I forgot that the result of "?:" is, in fact, an lvalue, the problem
was that
there was casting on the rhs. After I did

istream& input1=ss;
istream& input2=ifs;

istream& input (use_stringstream ? input1 : input2);

it worked.
 
M

Michael DOUBEZ

(e-mail address removed) a écrit :
Yes, I tried that, and wrote about it in the remainder of my post.

The problem with the reference was that I need an lvalue on the
right hand side.

I forgot that the result of "?:" is, in fact, an lvalue, the problem
was that
there was casting on the rhs.

A cast you do yourself ?

If ss and ifs inherits from ostream, there shouldn't be any problem: the
cast is implicitely done.
After I did

istream& input1=ss;
istream& input2=ifs;

I don't see how that solved your problem, you cannot take the non-const
reference of a r-value. Unless your r-value is some kind of proxy.
istream& input (use_stringstream ? input1 : input2);

it worked.

Good for you.
 
J

jacek.dziedzic

A cast you do yourself ?

No, in fact is was a cast done by the compiler. I didn't mention the
fact that ifs was, in fact, a class derived from ifstream, not
ifstream
itself.
I don't see how that solved your problem, you cannot take the non-const
reference of a r-value. Unless your r-value is some kind of proxy.

I thought it moved the casting out of the ternary operator,
which then could be used as an lvalue.

Thanks for your help.

- J.
 
J

James Kanze

(e-mail address removed) a écrit :
A cast you do yourself ?
If ss and ifs inherits from ostream, there shouldn't be any
problem: the cast is implicitely done.

It shouldn't be. The type of the second operand can be
converted to that of the third, or vice versa, but the compiler
isn't supposed to look for a possible type to which both can be
converted. So you have to write something like:

std::istream& input = use_stringstream
? (static_cast< std::istream& >( ss )
: ifs ;

(Obviously, you can just as well cast the third operand, or
both.)
I don't see how that solved your problem, you cannot take the
non-const reference of a r-value. Unless your r-value is some
kind of proxy.

Presumably, ss and ifs are not r-values. In fact, I don't see
how they could not be.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,059
Latest member
cryptoseoagencies

Latest Threads

Top